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
|
@@ -6,6 +6,7 @@ module RuboCop
|
|
|
6
6
|
class CommentConfig
|
|
7
7
|
extend SimpleForwardable
|
|
8
8
|
include DisableNext
|
|
9
|
+
include PushPop
|
|
9
10
|
|
|
10
11
|
CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY
|
|
11
12
|
|
|
@@ -75,20 +76,19 @@ module RuboCop
|
|
|
75
76
|
non_comment_token_line_numbers.none?(line_number)
|
|
76
77
|
end
|
|
77
78
|
|
|
78
|
-
# The names of the cops that are opted in by an `enable` comment directive
|
|
79
|
-
#
|
|
79
|
+
# The names of the cops that are opted in by an `enable` comment directive
|
|
80
|
+
# or a `+` argument of a `push`/`next` directive, used to mobilize cops
|
|
81
|
+
# disabled in the config on demand. Departments are expanded for the
|
|
82
|
+
# opt-in forms only: a plain `enable` naming a department usually just
|
|
83
|
+
# closes a `disable` of it, and expanding it would switch on every
|
|
84
|
+
# config-disabled cop of the department for the rest of the file.
|
|
80
85
|
#
|
|
81
86
|
# @api private
|
|
82
87
|
# @return [Set<String>]
|
|
83
88
|
def opt_in_cops
|
|
84
89
|
@opt_in_cops ||= begin
|
|
85
90
|
cops = Set.new
|
|
86
|
-
each_directive
|
|
87
|
-
next unless directive.enabled?
|
|
88
|
-
next if directive.all_cops?
|
|
89
|
-
|
|
90
|
-
cops.merge(directive.raw_cop_names)
|
|
91
|
-
end
|
|
91
|
+
each_directive { |directive| cops.merge(opted_in_by(directive)) }
|
|
92
92
|
cops
|
|
93
93
|
end
|
|
94
94
|
end
|
|
@@ -98,9 +98,7 @@ module RuboCop
|
|
|
98
98
|
def extra_enabled_comments_with_names(extras:, names:)
|
|
99
99
|
each_directive do |directive|
|
|
100
100
|
next unless comment_only_line?(directive.line_number)
|
|
101
|
-
|
|
102
|
-
# play no part in the disable/enable pairing.
|
|
103
|
-
next if directive.push? || directive.pop? || directive.disable_next?
|
|
101
|
+
next if self_closing_directive?(directive)
|
|
104
102
|
|
|
105
103
|
if directive.enabled_all?
|
|
106
104
|
handle_enable_all(directive, names, extras)
|
|
@@ -112,6 +110,18 @@ module RuboCop
|
|
|
112
110
|
extras
|
|
113
111
|
end
|
|
114
112
|
|
|
113
|
+
def opted_in_by(directive)
|
|
114
|
+
if directive.push? || directive.next?
|
|
115
|
+
directive.signed_args.fetch('+', []).flat_map { |name| expand_cop_name(name) }
|
|
116
|
+
elsif !directive.enabled? || directive.all_cops?
|
|
117
|
+
[]
|
|
118
|
+
elsif directive.enable_next?
|
|
119
|
+
directive.cop_names
|
|
120
|
+
else
|
|
121
|
+
directive.raw_cop_names
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
115
125
|
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
116
126
|
def analyze
|
|
117
127
|
return {} if @no_directives
|
|
@@ -128,6 +138,10 @@ module RuboCop
|
|
|
128
138
|
pop_state(analyses, directive.line_number) if @stack.any?
|
|
129
139
|
elsif directive.disable_next?
|
|
130
140
|
apply_disable_next(analyses, directive)
|
|
141
|
+
elsif directive.next?
|
|
142
|
+
apply_next_directive(analyses, resolve_push_cops(directive), directive)
|
|
143
|
+
elsif directive.enable_next?
|
|
144
|
+
apply_enable_next(analyses, directive)
|
|
131
145
|
else
|
|
132
146
|
directive.cop_names.each do |cop_name|
|
|
133
147
|
cop_name = qualified_cop_name(cop_name)
|
|
@@ -144,48 +158,6 @@ module RuboCop
|
|
|
144
158
|
end
|
|
145
159
|
end
|
|
146
160
|
|
|
147
|
-
def resolve_push_cops(directive)
|
|
148
|
-
directive.push_args.transform_values do |names|
|
|
149
|
-
names.flat_map { |name| expand_cop_name(name) }
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def expand_cop_name(name)
|
|
154
|
-
registry = Cop::Registry.global
|
|
155
|
-
cops = registry.department?(name) ? registry.names_for_department(name) : [name]
|
|
156
|
-
cops.map { |c| qualified_cop_name(c) }
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def apply_push(analyses, resolved_cops, directive)
|
|
160
|
-
resolved_cops.each do |op, cops|
|
|
161
|
-
cops.each { |cop| apply_cop_op(analyses, op, cop, directive) }
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def apply_cop_op(analyses, operation, cop, directive)
|
|
166
|
-
analysis = analyses[cop]
|
|
167
|
-
line = directive.line_number
|
|
168
|
-
if operation == '-' && !analysis.start_line_number
|
|
169
|
-
analyses[cop] = CopAnalysis.new(analysis.line_ranges, line, directive)
|
|
170
|
-
elsif operation == '+' && analysis.start_line_number
|
|
171
|
-
analyses[cop] = CopAnalysis.new(analysis.close(line), nil)
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def pop_state(analyses, line)
|
|
176
|
-
restore_point = @stack.pop
|
|
177
|
-
(restore_point.keys | analyses.keys).each do |cop|
|
|
178
|
-
analyses[cop] = popped_analysis(analyses[cop], restore_point[cop], line)
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def popped_analysis(current, restored, line)
|
|
183
|
-
ranges = current.close(line - 1)
|
|
184
|
-
return CopAnalysis.new(ranges, nil) unless restored&.start_line_number
|
|
185
|
-
|
|
186
|
-
CopAnalysis.new(ranges, line, restored.start_directive)
|
|
187
|
-
end
|
|
188
|
-
|
|
189
161
|
def inject_disabled_cops_directives(analyses)
|
|
190
162
|
registry.disabled_names(config).each do |cop_name|
|
|
191
163
|
analyses[cop_name] = analyze_cop(
|
|
@@ -236,6 +208,13 @@ module RuboCop
|
|
|
236
208
|
end
|
|
237
209
|
end
|
|
238
210
|
|
|
211
|
+
# Push/pop and next-statement directives close themselves, so they
|
|
212
|
+
# play no part in the disable/enable pairing.
|
|
213
|
+
def self_closing_directive?(directive)
|
|
214
|
+
directive.push? || directive.pop? || directive.disable_next? ||
|
|
215
|
+
directive.next? || directive.enable_next?
|
|
216
|
+
end
|
|
217
|
+
|
|
239
218
|
def qualified_cop_name(cop_name)
|
|
240
219
|
# A directive naming a cop under the wrong department is not honored -
|
|
241
220
|
# the mistake is surfaced by `Lint/RedundantCopDisableDirective` (with a
|
data/lib/rubocop/config.rb
CHANGED
|
@@ -226,6 +226,16 @@ module RuboCop
|
|
|
226
226
|
end
|
|
227
227
|
end
|
|
228
228
|
|
|
229
|
+
# Whether preview behavior is on, for cops that gate an unstable change
|
|
230
|
+
# behind it and for cops that are themselves `Enabled: preview`.
|
|
231
|
+
# `--preview` / `--no-preview` win over `AllCops: Preview`.
|
|
232
|
+
def preview?(options = {})
|
|
233
|
+
preview = options[:preview]
|
|
234
|
+
return preview unless preview.nil?
|
|
235
|
+
|
|
236
|
+
for_all_cops['Preview'] == true
|
|
237
|
+
end
|
|
238
|
+
|
|
229
239
|
def active_support_extensions_enabled?
|
|
230
240
|
for_all_cops['ActiveSupportExtensionsEnabled']
|
|
231
241
|
end
|
|
@@ -24,7 +24,8 @@ module RuboCop
|
|
|
24
24
|
include FileFinder
|
|
25
25
|
|
|
26
26
|
attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
|
|
27
|
-
:enabled_by_default, :disabled_by_default, :ignore_unrecognized_cops
|
|
27
|
+
:enabled_by_default, :disabled_by_default, :ignore_unrecognized_cops,
|
|
28
|
+
:preview
|
|
28
29
|
attr_writer :default_configuration, :cache_root
|
|
29
30
|
attr_reader :loaded_plugins, :loaded_features
|
|
30
31
|
|
|
@@ -41,6 +42,7 @@ module RuboCop
|
|
|
41
42
|
@loaded_features = Set.new
|
|
42
43
|
@disable_pending_cops = nil
|
|
43
44
|
@enable_pending_cops = nil
|
|
45
|
+
@preview = nil
|
|
44
46
|
@enabled_by_default = nil
|
|
45
47
|
@disabled_by_default = nil
|
|
46
48
|
@ignore_parent_exclusion = nil
|
|
@@ -171,7 +173,8 @@ module RuboCop
|
|
|
171
173
|
hash = ConfigLoader.load_yaml_configuration(path)
|
|
172
174
|
config = Config.new(hash, path).tap(&:make_excludes_absolute)
|
|
173
175
|
|
|
174
|
-
@default_configuration =
|
|
176
|
+
@default_configuration =
|
|
177
|
+
ConfigLoader.merge_with_default(config, path, resolve_preview: false)
|
|
175
178
|
end
|
|
176
179
|
|
|
177
180
|
# Returns the path RuboCop inferred as the root of the project. No file
|
|
@@ -187,20 +190,28 @@ module RuboCop
|
|
|
187
190
|
end
|
|
188
191
|
|
|
189
192
|
# Merges the given configuration with the default one.
|
|
190
|
-
def merge_with_default(config, config_file, unset_nil: true)
|
|
191
|
-
resolver.merge_with_default(
|
|
193
|
+
def merge_with_default(config, config_file, unset_nil: true, resolve_preview: true)
|
|
194
|
+
resolver.merge_with_default(
|
|
195
|
+
config, config_file, unset_nil: unset_nil, resolve_preview: resolve_preview
|
|
196
|
+
)
|
|
192
197
|
end
|
|
193
198
|
|
|
194
199
|
# Applies CLI overrides for `AllCops/EnabledByDefault` and
|
|
195
200
|
# `AllCops/DisabledByDefault` to the given configuration. Used when the
|
|
196
201
|
# configuration would otherwise be returned without going through
|
|
197
202
|
# `merge_with_default` (e.g. there is no user-supplied `.rubocop.yml`).
|
|
203
|
+
# Used when there is no configuration file, so the defaults are the whole
|
|
204
|
+
# configuration and still need the same treatment `merge_with_default`
|
|
205
|
+
# would have given them.
|
|
198
206
|
def apply_default_overrides(config)
|
|
199
|
-
|
|
207
|
+
hash = resolver.apply_preview_defaults(config, preview == true)
|
|
200
208
|
|
|
201
|
-
|
|
202
|
-
|
|
209
|
+
unless @enabled_by_default.nil? && @disabled_by_default.nil?
|
|
210
|
+
hash = hash.transform_values do |params|
|
|
211
|
+
params.is_a?(Hash) ? params.merge('Enabled' => !@disabled_by_default) : params
|
|
212
|
+
end
|
|
203
213
|
end
|
|
214
|
+
|
|
204
215
|
Config.new(hash, config.loaded_path)
|
|
205
216
|
end
|
|
206
217
|
|
|
@@ -37,8 +37,9 @@ module RuboCop
|
|
|
37
37
|
|
|
38
38
|
def resolve_inheritance(path, hash, file, debug) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
39
39
|
inherited_files = Array(hash['inherit_from'])
|
|
40
|
-
base_configs(path, inherited_files, file)
|
|
41
|
-
|
|
40
|
+
base_configs = base_configs(path, inherited_files, file)
|
|
41
|
+
preview = inherited_preview?(hash, base_configs)
|
|
42
|
+
base_configs.each_with_index.reverse_each do |base_config, index|
|
|
42
43
|
override_department_setting_for_cops(base_config, hash)
|
|
43
44
|
override_enabled_for_disabled_departments(base_config, hash)
|
|
44
45
|
|
|
@@ -50,7 +51,7 @@ module RuboCop
|
|
|
50
51
|
v = merge(v, hash[k],
|
|
51
52
|
cop_name: k, file: file, debug: debug,
|
|
52
53
|
inherited_file: inherited_files[index],
|
|
53
|
-
inherit_mode: determine_inherit_mode(hash, k))
|
|
54
|
+
inherit_mode: determine_inherit_mode(hash, k, preview))
|
|
54
55
|
end
|
|
55
56
|
hash[k] = v
|
|
56
57
|
fix_include_paths(base_config.loaded_path, hash, path, k, v) if only_base_has_include
|
|
@@ -94,20 +95,28 @@ module RuboCop
|
|
|
94
95
|
# only cops explicitly disabled in user configuration are disabled.
|
|
95
96
|
# When the `--disable-all-cops` or `--enable-all-cops` CLI option is given,
|
|
96
97
|
# it takes precedence over the configuration values.
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
#
|
|
99
|
+
# With `resolve_preview: false` the `Preview` sections of the default
|
|
100
|
+
# configuration are left in place and preview is treated as off. That is
|
|
101
|
+
# what extending the default configuration itself needs: preview gets
|
|
102
|
+
# applied later, when a project configuration is resolved against it.
|
|
103
|
+
def merge_with_default(config, config_file, unset_nil:, resolve_preview: true)
|
|
104
|
+
base_defaults, preview = defaults_with_preview(config, resolve_preview)
|
|
105
|
+
default_configuration = base_defaults
|
|
99
106
|
disabled_by_default, enabled_by_default = resolve_default_overrides(config)
|
|
100
107
|
|
|
101
108
|
if disabled_by_default || enabled_by_default
|
|
102
|
-
default_configuration = transform(
|
|
109
|
+
default_configuration = transform(base_defaults) do |params|
|
|
103
110
|
params.merge('Enabled' => !disabled_by_default)
|
|
104
111
|
end
|
|
105
112
|
end
|
|
106
113
|
|
|
107
|
-
|
|
114
|
+
if disabled_by_default
|
|
115
|
+
config = handle_disabled_by_default(config, default_configuration, base_defaults)
|
|
116
|
+
end
|
|
108
117
|
override_enabled_for_disabled_departments(default_configuration, config)
|
|
109
118
|
|
|
110
|
-
opts = { inherit_mode: config
|
|
119
|
+
opts = { inherit_mode: inherit_mode_for_default(config, preview), unset_nil: unset_nil }
|
|
111
120
|
Config.new(merge(default_configuration, config, **opts), config_file)
|
|
112
121
|
end
|
|
113
122
|
|
|
@@ -166,8 +175,55 @@ module RuboCop
|
|
|
166
175
|
end
|
|
167
176
|
end
|
|
168
177
|
|
|
178
|
+
# A cop's entry in the default configuration may carry a `Preview` section
|
|
179
|
+
# with the defaults it is expected to adopt in the next major release. Under
|
|
180
|
+
# `Preview` those replace the current defaults. The section is dropped either
|
|
181
|
+
# way, so the resolved configuration only ever shows what is in effect.
|
|
182
|
+
def apply_preview_defaults(default_configuration, preview)
|
|
183
|
+
transform(default_configuration) do |params|
|
|
184
|
+
next params unless params['Preview'].is_a?(Hash)
|
|
185
|
+
|
|
186
|
+
params = params.dup
|
|
187
|
+
preview_params = params.delete('Preview')
|
|
188
|
+
preview ? params.merge(preview_params) : params
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
169
192
|
private
|
|
170
193
|
|
|
194
|
+
def defaults_with_preview(config, resolve_preview)
|
|
195
|
+
defaults = ConfigLoader.default_configuration
|
|
196
|
+
return [defaults, false] unless resolve_preview
|
|
197
|
+
|
|
198
|
+
preview = preview?(config)
|
|
199
|
+
[apply_preview_defaults(defaults, preview), preview]
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def inherit_mode_for_default(config, preview)
|
|
203
|
+
with_preview_exclude_merge(config['inherit_mode'] || {}, preview)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Under `Preview`, `Exclude` is merged rather than replaced, so that excluding
|
|
207
|
+
# one directory does not silently drop the excludes it would have inherited -
|
|
208
|
+
# from the default configuration or from a file named in `inherit_from`. An
|
|
209
|
+
# explicit `inherit_mode` still wins, in either direction.
|
|
210
|
+
def with_preview_exclude_merge(mode, preview)
|
|
211
|
+
return mode unless preview
|
|
212
|
+
return mode if Array(mode['override']).include?('Exclude')
|
|
213
|
+
return mode if Array(mode['merge']).include?('Exclude')
|
|
214
|
+
|
|
215
|
+
mode.merge('merge' => Array(mode['merge']) + ['Exclude'])
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# `config` has already been through `handle_disabled_by_default` by this
|
|
219
|
+
# point, which returns a plain hash, so read `AllCops` directly rather than
|
|
220
|
+
# going through `Config#for_all_cops`.
|
|
221
|
+
def preview?(config)
|
|
222
|
+
return ConfigLoader.preview unless ConfigLoader.preview.nil?
|
|
223
|
+
|
|
224
|
+
(config['AllCops'] || {})['Preview'] == true
|
|
225
|
+
end
|
|
226
|
+
|
|
171
227
|
def resolve_default_overrides(config)
|
|
172
228
|
if ConfigLoader.disabled_by_default || ConfigLoader.enabled_by_default
|
|
173
229
|
[ConfigLoader.disabled_by_default, ConfigLoader.enabled_by_default]
|
|
@@ -207,10 +263,21 @@ module RuboCop
|
|
|
207
263
|
"the same parameter in #{opts[:inherited_file]}"
|
|
208
264
|
end
|
|
209
265
|
|
|
210
|
-
|
|
266
|
+
# The `AllCops: Preview` in effect once inheritance is resolved: the file
|
|
267
|
+
# itself wins, then the files it inherits from, last one first. It has to be
|
|
268
|
+
# known before merging, since the keys are merged in whatever order they
|
|
269
|
+
# appear and `AllCops` may well come after the cops whose `Exclude` it affects.
|
|
270
|
+
def inherited_preview?(hash, base_configs)
|
|
271
|
+
all_cops = [hash, *base_configs.reverse].map { |config| config['AllCops'] }.find do |params|
|
|
272
|
+
params.is_a?(Hash) && params.key?('Preview')
|
|
273
|
+
end
|
|
274
|
+
preview?('AllCops' => all_cops)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def determine_inherit_mode(hash, key, preview)
|
|
211
278
|
cop_cfg = hash[key]
|
|
212
279
|
local_inherit = cop_cfg['inherit_mode'] if cop_cfg.is_a?(Hash)
|
|
213
|
-
local_inherit || hash['inherit_mode'] || {}
|
|
280
|
+
with_preview_exclude_merge(local_inherit || hash['inherit_mode'] || {}, preview)
|
|
214
281
|
end
|
|
215
282
|
|
|
216
283
|
def should_union?(derived_hash, base_hash, root_mode, key)
|
|
@@ -276,7 +343,7 @@ module RuboCop
|
|
|
276
343
|
file.is_a?(RemoteConfig)
|
|
277
344
|
end
|
|
278
345
|
|
|
279
|
-
def handle_disabled_by_default(config, new_default_configuration)
|
|
346
|
+
def handle_disabled_by_default(config, new_default_configuration, base_defaults)
|
|
280
347
|
department_config = config.to_hash.reject { |cop| cop.include?('/') }
|
|
281
348
|
department_config.each do |dept, dept_params|
|
|
282
349
|
next unless dept_params['Enabled']
|
|
@@ -285,7 +352,7 @@ module RuboCop
|
|
|
285
352
|
next unless cop.start_with?("#{dept}/")
|
|
286
353
|
|
|
287
354
|
# Retain original default configuration for cops in the department.
|
|
288
|
-
params['Enabled'] =
|
|
355
|
+
params['Enabled'] = base_defaults[cop]['Enabled']
|
|
289
356
|
end
|
|
290
357
|
end
|
|
291
358
|
|
|
@@ -20,7 +20,8 @@ module RuboCop
|
|
|
20
20
|
rule_message + "\n(obsolete configuration found in #{smart_loaded_path}, please update it)"
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
#
|
|
23
|
+
# Failure by default; rules that accept `severity: warning` say so
|
|
24
|
+
# themselves.
|
|
24
25
|
def warning?
|
|
25
26
|
false
|
|
26
27
|
end
|
|
@@ -20,15 +20,23 @@ module RuboCop
|
|
|
20
20
|
|
|
21
21
|
if reason
|
|
22
22
|
"#{base} since #{reason.chomp}."
|
|
23
|
-
elsif alternatives
|
|
23
|
+
elsif alternatives.any?
|
|
24
24
|
"#{base}. Please use #{to_sentence(alternatives, connector: 'and/or')} instead."
|
|
25
25
|
else
|
|
26
26
|
"#{base}."
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def warning?
|
|
31
|
+
severity == 'warning'
|
|
32
|
+
end
|
|
33
|
+
|
|
30
34
|
private
|
|
31
35
|
|
|
36
|
+
def severity
|
|
37
|
+
metadata['severity']
|
|
38
|
+
end
|
|
39
|
+
|
|
32
40
|
def reason
|
|
33
41
|
metadata['reason']
|
|
34
42
|
end
|
|
@@ -15,7 +15,7 @@ module RuboCop
|
|
|
15
15
|
'changed_parameters' => ChangedParameter,
|
|
16
16
|
'changed_enforced_styles' => ChangedEnforcedStyles
|
|
17
17
|
}.freeze
|
|
18
|
-
LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant
|
|
18
|
+
LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant -- a cache, written to at runtime
|
|
19
19
|
private_constant :LOAD_RULES_CACHE
|
|
20
20
|
|
|
21
21
|
attr_reader :rules, :warnings
|
|
@@ -11,7 +11,7 @@ module RuboCop
|
|
|
11
11
|
COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details
|
|
12
12
|
Enabled Reference References Safe SafeAutoCorrect].freeze
|
|
13
13
|
# @api private
|
|
14
|
-
INTERNAL_PARAMS = %w[Description StyleGuide
|
|
14
|
+
INTERNAL_PARAMS = %w[Description StyleGuide Preview
|
|
15
15
|
VersionAdded VersionChanged VersionRemoved
|
|
16
16
|
Reference References Safe SafeAutoCorrect].freeze
|
|
17
17
|
# @api private
|
|
@@ -21,7 +21,7 @@ module RuboCop
|
|
|
21
21
|
|
|
22
22
|
# @api private
|
|
23
23
|
CONFIG_CHECK_KEYS = %w[Enabled Safe SafeAutoCorrect AutoCorrect References].to_set.freeze
|
|
24
|
-
CONFIG_CHECK_DEPARTMENTS = %w[pending override_department].freeze
|
|
24
|
+
CONFIG_CHECK_DEPARTMENTS = %w[pending preview override_department].freeze
|
|
25
25
|
CONFIG_CHECK_AUTOCORRECTS = %w[always contextual disabled].freeze
|
|
26
26
|
private_constant :CONFIG_CHECK_KEYS, :CONFIG_CHECK_DEPARTMENTS
|
|
27
27
|
|
|
@@ -48,7 +48,7 @@ module RuboCop
|
|
|
48
48
|
|
|
49
49
|
check_obsoletions
|
|
50
50
|
alert_about_unrecognized_cops(invalid_cop_names)
|
|
51
|
-
|
|
51
|
+
validate_all_cops_parameters
|
|
52
52
|
validate_parameter_names(valid_cop_names)
|
|
53
53
|
validate_enforced_styles(valid_cop_names)
|
|
54
54
|
validate_syntax_cop
|
|
@@ -170,6 +170,32 @@ module RuboCop
|
|
|
170
170
|
validate_department_new_cops_parameters
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
+
def validate_all_cops_parameters
|
|
174
|
+
validate_new_cops_parameter
|
|
175
|
+
validate_fail_level_parameter
|
|
176
|
+
validate_preview_parameter
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def validate_fail_level_parameter
|
|
180
|
+
fail_level = @config.for_all_cops['FailLevel']
|
|
181
|
+
return if fail_level.nil? || Cop::Severity::NAMES.include?(fail_level.to_sym)
|
|
182
|
+
|
|
183
|
+
message = "invalid #{fail_level} for `FailLevel` found in #{smart_loaded_path}\n" \
|
|
184
|
+
"Valid choices are: #{Cop::Severity::NAMES.join(', ')}"
|
|
185
|
+
|
|
186
|
+
raise ValidationError, message
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def validate_preview_parameter
|
|
190
|
+
preview = @config.for_all_cops['Preview']
|
|
191
|
+
return if [nil, true, false].include?(preview)
|
|
192
|
+
|
|
193
|
+
message = "invalid #{preview} for `Preview` found in #{smart_loaded_path}\n" \
|
|
194
|
+
'Valid choices are: true, false'
|
|
195
|
+
|
|
196
|
+
raise ValidationError, message
|
|
197
|
+
end
|
|
198
|
+
|
|
173
199
|
def validate_all_cops_new_cops_parameter
|
|
174
200
|
new_cop_parameter = @config.for_all_cops['NewCops']
|
|
175
201
|
return if new_cop_parameter.nil? || NEW_COPS_VALUES.include?(new_cop_parameter)
|
|
@@ -40,12 +40,9 @@ module RuboCop
|
|
|
40
40
|
# allow turning off autocorrect on a cop by cop basis
|
|
41
41
|
return true unless cop_config
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
return false if ['disabled', false].include?(cop_config['AutoCorrect'])
|
|
43
|
+
return false if disabled_autocorrect?
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
# source code, and autocorrection with `AutoCorrect: contextual` will not be performed.
|
|
48
|
-
return false if contextual_autocorrect? && LSP.enabled?
|
|
45
|
+
return false if contextual_autocorrect_held_back?
|
|
49
46
|
|
|
50
47
|
# :safe_autocorrect is a derived option based on several command-line
|
|
51
48
|
# arguments - see RuboCop::Options#add_autocorrection_options
|
|
@@ -56,6 +53,14 @@ module RuboCop
|
|
|
56
53
|
|
|
57
54
|
private
|
|
58
55
|
|
|
56
|
+
# When LSP is enabled or the `--editor-mode` option is on, it is considered as editing
|
|
57
|
+
# source code, and autocorrection with `AutoCorrect: contextual` will not be performed.
|
|
58
|
+
# The `editing` option says the same without the rest of LSP mode, which
|
|
59
|
+
# is about showing offenses in an editor.
|
|
60
|
+
def contextual_autocorrect_held_back?
|
|
61
|
+
contextual_autocorrect? && (LSP.enabled? || @options.fetch(:editing, false))
|
|
62
|
+
end
|
|
63
|
+
|
|
59
64
|
def disable_offense(offense_range)
|
|
60
65
|
unbreakable_range = multiline_ranges(offense_range)&.find do |range|
|
|
61
66
|
offense_range.overlaps?(range) &&
|
data/lib/rubocop/cop/badge.rb
CHANGED
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
|
45
45
|
|
|
46
46
|
def hash
|
|
47
47
|
# Do hashing manually to reduce Array allocations.
|
|
48
|
-
department.hash ^ cop_name.hash # rubocop:disable Security/CompoundHash
|
|
48
|
+
department.hash ^ cop_name.hash # rubocop:disable Security/CompoundHash -- hashing manually avoids the Array allocation
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def match?(other)
|
data/lib/rubocop/cop/base.rb
CHANGED
|
@@ -49,7 +49,12 @@ module RuboCop
|
|
|
49
49
|
InvestigationReport = Struct.new(:cop, :processed_source, :offenses, :corrector)
|
|
50
50
|
|
|
51
51
|
# List of methods names to restrict calls for `on_send` / `on_csend`
|
|
52
|
-
RESTRICT_ON_SEND = Set[].freeze # rubocop:disable InternalAffairs/UselessRestrictOnSend
|
|
52
|
+
RESTRICT_ON_SEND = Set[].freeze # rubocop:disable InternalAffairs/UselessRestrictOnSend -- the base class default, which cops override
|
|
53
|
+
|
|
54
|
+
# Departments whose cops report above `convention` unless a cop says
|
|
55
|
+
# otherwise. The exceptions live in `config/default.yml` as an explicit
|
|
56
|
+
# `Severity`, such as the lint-like cops in `Bundler` and `Gemspec`.
|
|
57
|
+
DEPARTMENT_SEVERITIES = { Lint: :warning, Security: :warning, Metrics: :refactor }.freeze
|
|
53
58
|
|
|
54
59
|
# List of cops that should not try to autocorrect at the same
|
|
55
60
|
# time as this cop
|
|
@@ -211,14 +216,8 @@ module RuboCop
|
|
|
211
216
|
message = find_message(range_to_pass, message)
|
|
212
217
|
|
|
213
218
|
status, corrector = enabled_lines?(range) ? correct(range, &block) : :disabled
|
|
214
|
-
justification = suppression_reason(range) if status == :disabled
|
|
215
|
-
|
|
216
|
-
# Since this range may be generated from Ruby code embedded in some
|
|
217
|
-
# template file, we convert it to location info in the original file.
|
|
218
|
-
range = range_for_original(range)
|
|
219
219
|
|
|
220
|
-
current_offenses <<
|
|
221
|
-
justification: justification)
|
|
220
|
+
current_offenses << new_offense(range, severity, message, status, corrector)
|
|
222
221
|
end
|
|
223
222
|
|
|
224
223
|
# This method should be overridden when a cop's behavior depends
|
|
@@ -266,10 +265,21 @@ module RuboCop
|
|
|
266
265
|
@config.target_ruby_version
|
|
267
266
|
end
|
|
268
267
|
|
|
269
|
-
# Returns a
|
|
270
|
-
#
|
|
268
|
+
# Returns the version of a gem in the target, by default its locked version
|
|
269
|
+
# (i.e. from Gemfile.lock or gems.locked).
|
|
270
|
+
#
|
|
271
|
+
# The requirements declared with `requires_gem` are checked against the version
|
|
272
|
+
# this method returns, so an extension that lets users state the version of its
|
|
273
|
+
# gem in `AllCops` (e.g. `TargetFrameworkVersion`) can override it for that gem,
|
|
274
|
+
# returning a `Gem::Version`, and fall back to `super` for any other gem.
|
|
275
|
+
#
|
|
276
|
+
# @param [String] gem_name
|
|
277
|
+
# @return [Gem::Version, nil] The gem version, or nil if the gem is not present.
|
|
278
|
+
#
|
|
279
|
+
# @api public
|
|
271
280
|
def target_gem_version(gem_name)
|
|
272
|
-
|
|
281
|
+
gem_versions = @config.gem_versions_in_target
|
|
282
|
+
gem_versions && gem_versions[gem_name]
|
|
273
283
|
end
|
|
274
284
|
|
|
275
285
|
def parser_engine
|
|
@@ -288,6 +298,13 @@ module RuboCop
|
|
|
288
298
|
@config.string_literals_frozen_by_default?
|
|
289
299
|
end
|
|
290
300
|
|
|
301
|
+
# Whether the user opted in to unstable behavior, with `--preview` or
|
|
302
|
+
# `AllCops: Preview`. Cops branch on this to ship a change that is not
|
|
303
|
+
# ready to be the default yet.
|
|
304
|
+
def preview?
|
|
305
|
+
@config.preview?(@options)
|
|
306
|
+
end
|
|
307
|
+
|
|
291
308
|
def relevant_file?(file)
|
|
292
309
|
return false unless target_satisfies_all_gem_version_requirements?
|
|
293
310
|
return true unless @config.clusivity_config_for_badge?(self.class.badge)
|
|
@@ -326,7 +343,7 @@ module RuboCop
|
|
|
326
343
|
|
|
327
344
|
### Reserved for Commissioner
|
|
328
345
|
|
|
329
|
-
# rubocop:disable Layout/ClassStructure
|
|
346
|
+
# rubocop:disable Layout/ClassStructure -- grouped under the Commissioner heading above
|
|
330
347
|
# @api private
|
|
331
348
|
def callbacks_needed
|
|
332
349
|
self.class.callbacks_needed
|
|
@@ -370,6 +387,12 @@ module RuboCop
|
|
|
370
387
|
cop_config.fetch('AutoCorrect', 'always') == 'contextual'
|
|
371
388
|
end
|
|
372
389
|
|
|
390
|
+
# @api private
|
|
391
|
+
def disabled_autocorrect?
|
|
392
|
+
# `false` is the same as `'disabled'` for backward compatibility.
|
|
393
|
+
['disabled', false].include?(cop_config['AutoCorrect'])
|
|
394
|
+
end
|
|
395
|
+
|
|
373
396
|
def inspect # :nodoc:
|
|
374
397
|
"#<#{self.class.name}:#{object_id} @config=#{@config} @options=#{@options}>"
|
|
375
398
|
end
|
|
@@ -382,6 +405,22 @@ module RuboCop
|
|
|
382
405
|
@restrict_on_send ||= self::RESTRICT_ON_SEND.to_a.freeze
|
|
383
406
|
end
|
|
384
407
|
|
|
408
|
+
# @return [Offense]
|
|
409
|
+
def new_offense(range, severity, message, status, corrector)
|
|
410
|
+
justification = suppression_reason(range) if status == :disabled
|
|
411
|
+
|
|
412
|
+
# Since this range may be generated from Ruby code embedded in some
|
|
413
|
+
# template file, we convert it to location info in the original file.
|
|
414
|
+
# A cop configured with `AutoCorrect: false` reports no edits, since
|
|
415
|
+
# nothing that honors the configuration applies them. The corrector
|
|
416
|
+
# stays, so an editor can still offer it as a quick fix to choose.
|
|
417
|
+
corrections = [] if corrector && disabled_autocorrect?
|
|
418
|
+
|
|
419
|
+
Offense.new(severity, range_for_original(range), message, name, status, corrector,
|
|
420
|
+
justification: justification, correction_safe: safe_autocorrect?,
|
|
421
|
+
corrections: corrections)
|
|
422
|
+
end
|
|
423
|
+
|
|
385
424
|
### Reserved for Cop::Cop
|
|
386
425
|
|
|
387
426
|
def callback_argument(range)
|
|
@@ -453,7 +492,8 @@ module RuboCop
|
|
|
453
492
|
# The unsafe correction will not run, so the offense is
|
|
454
493
|
# uncorrectable for this run and gets a todo comment.
|
|
455
494
|
attempt_correction(range, nil)
|
|
456
|
-
elsif corrector && (always_autocorrect? ||
|
|
495
|
+
elsif corrector && (always_autocorrect? ||
|
|
496
|
+
(contextual_autocorrect? && !contextual_autocorrect_held_back?))
|
|
457
497
|
:uncorrected
|
|
458
498
|
else
|
|
459
499
|
:unsupported
|
|
@@ -561,7 +601,7 @@ module RuboCop
|
|
|
561
601
|
end
|
|
562
602
|
|
|
563
603
|
def default_severity
|
|
564
|
-
self.class.
|
|
604
|
+
DEPARTMENT_SEVERITIES.fetch(self.class.department, :convention)
|
|
565
605
|
end
|
|
566
606
|
|
|
567
607
|
def custom_severity
|
|
@@ -589,17 +629,10 @@ module RuboCop
|
|
|
589
629
|
end
|
|
590
630
|
|
|
591
631
|
def target_satisfies_all_gem_version_requirements?
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
gem_requirements.all? do |gem_name, version_req|
|
|
596
|
-
all_gem_versions_in_target = @config.gem_versions_in_target
|
|
597
|
-
next false unless all_gem_versions_in_target
|
|
598
|
-
|
|
599
|
-
gem_version_in_target = all_gem_versions_in_target[gem_name]
|
|
600
|
-
next false unless gem_version_in_target
|
|
632
|
+
self.class.gem_requirements.all? do |gem_name, version_requirement|
|
|
633
|
+
gem_version = target_gem_version(gem_name)
|
|
601
634
|
|
|
602
|
-
|
|
635
|
+
gem_version && version_requirement.satisfied_by?(gem_version)
|
|
603
636
|
end
|
|
604
637
|
end
|
|
605
638
|
end
|