rubocop 1.89.0 → 1.91.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/config/default.yml +309 -14
- data/config/obsoletion.yml +9 -0
- data/exe/rubocop +1 -1
- data/lib/rubocop/cached_data.rb +7 -2
- data/lib/rubocop/changed_files.rb +112 -0
- data/lib/rubocop/cli/command/execute_runner.rb +52 -1
- data/lib/rubocop/cli.rb +11 -7
- data/lib/rubocop/comment_config/directive_range.rb +34 -0
- data/lib/rubocop/comment_config/disable_next.rb +143 -0
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +50 -64
- data/lib/rubocop/config.rb +33 -5
- data/lib/rubocop/config_loader.rb +13 -6
- data/lib/rubocop/config_loader_resolver.rb +50 -9
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/removed_cop.rb +8 -0
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +19 -5
- data/lib/rubocop/cop/autocorrect_logic.rb +8 -0
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +49 -5
- data/lib/rubocop/cop/corrector.rb +3 -3
- data/lib/rubocop/cop/correctors.rb +2 -2
- 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 +1 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/class_structure.rb +102 -26
- data/lib/rubocop/cop/layout/comment_indentation.rb +8 -5
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +105 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +21 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +17 -4
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -5
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/line_length.rb +20 -3
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -2
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +14 -3
- data/lib/rubocop/cop/layout/space_around_operators.rb +12 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -4
- data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -0
- data/lib/rubocop/cop/lint/constant_reassignment.rb +17 -11
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +165 -15
- data/lib/rubocop/cop/lint/deprecated_reference.rb +11 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +113 -15
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +1 -2
- data/lib/rubocop/cop/lint/literal_as_condition.rb +11 -8
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +3 -6
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +185 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +25 -12
- data/lib/rubocop/cop/lint/name_typo.rb +53 -6
- 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/out_of_range_regexp_ref.rb +15 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +17 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +122 -29
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +47 -7
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -2
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -4
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +1 -2
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -2
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -2
- data/lib/rubocop/cop/lint/unused_private_method.rb +94 -17
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +36 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -2
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +61 -7
- data/lib/rubocop/cop/lint/void.rb +1 -2
- data/lib/rubocop/cop/lint.rb +3 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
- data/lib/rubocop/cop/migration/department_name.rb +1 -2
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +11 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +7 -4
- data/lib/rubocop/cop/mixin/hash_subset.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +7 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +62 -6
- data/lib/rubocop/cop/mixin/range_help.rb +1 -2
- data/lib/rubocop/cop/mixin/statement_modifier.rb +13 -7
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
- data/lib/rubocop/cop/mixin.rb +6 -2
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +16 -0
- 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/memoized_instance_variable_name.rb +2 -4
- data/lib/rubocop/cop/naming/method_name.rb +5 -2
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -2
- data/lib/rubocop/cop/offense.rb +27 -4
- data/lib/rubocop/cop/registry.rb +43 -11
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +5 -8
- data/lib/rubocop/cop/style/array_first_last.rb +1 -2
- data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -6
- data/lib/rubocop/cop/style/case_like_if.rb +5 -7
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +1 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -2
- data/lib/rubocop/cop/style/constant_visibility.rb +6 -3
- data/lib/rubocop/cop/style/copyright.rb +1 -2
- data/lib/rubocop/cop/style/data_inheritance.rb +14 -0
- data/lib/rubocop/cop/style/directive_scope.rb +304 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +83 -13
- data/lib/rubocop/cop/style/documentation_method.rb +1 -9
- 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_case_condition.rb +1 -2
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +12 -2
- data/lib/rubocop/cop/style/endless_method.rb +31 -12
- data/lib/rubocop/cop/style/file_null.rb +2 -2
- data/lib/rubocop/cop/style/float_division.rb +10 -16
- data/lib/rubocop/cop/style/for.rb +5 -0
- data/lib/rubocop/cop/style/format_string_token.rb +1 -2
- data/lib/rubocop/cop/style/guard_clause.rb +5 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
- data/lib/rubocop/cop/style/hash_lookup_method.rb +3 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -4
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +1 -2
- data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -2
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -2
- data/lib/rubocop/cop/style/negative_array_index.rb +2 -4
- data/lib/rubocop/cop/style/nested_modifier.rb +9 -4
- data/lib/rubocop/cop/style/nil_comparison.rb +36 -9
- 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 +3 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +1 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +6 -8
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +11 -3
- data/lib/rubocop/cop/style/redundant_each.rb +1 -2
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +2 -4
- data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -5
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -2
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +6 -6
- data/lib/rubocop/cop/style/redundant_return.rb +1 -2
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -2
- data/lib/rubocop/cop/style/sample.rb +11 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -2
- data/lib/rubocop/cop/style/semicolon.rb +2 -4
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +1 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +18 -5
- data/lib/rubocop/cop/style/struct_inheritance.rb +14 -0
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -2
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -2
- data/lib/rubocop/cop/style.rb +2 -1
- data/lib/rubocop/cop/team.rb +11 -3
- data/lib/rubocop/cop/util.rb +3 -5
- data/lib/rubocop/cop/variable_force/variable.rb +1 -2
- data/lib/rubocop/cops_documentation_generator.rb +26 -8
- data/lib/rubocop/directive_comment.rb +73 -10
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -1
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +2 -1
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +2 -4
- data/lib/rubocop/formatter/json_formatter.rb +11 -6
- data/lib/rubocop/formatter/junit_formatter.rb +26 -9
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -2
- data/lib/rubocop/formatter/sarif_formatter.rb +181 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -3
- data/lib/rubocop/formatter/tap_formatter.rb +3 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -2
- data/lib/rubocop/formatter.rb +1 -0
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +4 -8
- data/lib/rubocop/lsp/routes.rb +48 -19
- data/lib/rubocop/magic_comment.rb +27 -0
- data/lib/rubocop/mcp/server.rb +1 -2
- data/lib/rubocop/options.rb +69 -7
- data/lib/rubocop/path_util.rb +2 -3
- data/lib/rubocop/plugin/configuration_integrator.rb +6 -3
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/rake_task.rb +1 -2
- data/lib/rubocop/remote_config.rb +4 -4
- data/lib/rubocop/result_cache.rb +16 -5
- data/lib/rubocop/rspec/expect_offense.rb +2 -4
- data/lib/rubocop/rspec/shared_contexts.rb +4 -2
- data/lib/rubocop/runner.rb +90 -44
- data/lib/rubocop/server/cache.rb +1 -2
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +4 -1
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/version.rb +3 -5
- data/lib/rubocop.rb +7 -1
- data/lib/ruby_lsp/rubocop/addon.rb +1 -2
- metadata +18 -6
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Shared machinery for cops that compare a call site's arguments against
|
|
6
|
+
# a method signature from the project index (`Rubydex::Signature`).
|
|
7
|
+
#
|
|
8
|
+
# A signature is reduced to a shape - `[min, max, has_keywords]` where
|
|
9
|
+
# `max` is nil for a rest parameter - and the number of positional
|
|
10
|
+
# arguments a call passes is counted with Ruby's semantics for trailing
|
|
11
|
+
# keyword hashes: keywords passed to a method with no keyword parameters
|
|
12
|
+
# collapse into a single positional hash.
|
|
13
|
+
module IndexedMethodArity
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def arity_satisfied?(given, min, max)
|
|
17
|
+
given >= min && (max.nil? || given <= max)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def expected_range(min, max)
|
|
21
|
+
return "#{min}+" if max.nil?
|
|
22
|
+
return min.to_s if min == max
|
|
23
|
+
|
|
24
|
+
"#{min}..#{max}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The agreed `[min, max, has_keywords]` shape of an indexed member's
|
|
28
|
+
# method definitions, or nil when the member is not backed by plain
|
|
29
|
+
# method definitions (attr, alias), has no signature, forwards
|
|
30
|
+
# arguments, or its definitions disagree on arity (e.g. reopened with
|
|
31
|
+
# a different one).
|
|
32
|
+
def indexed_member_shape(member)
|
|
33
|
+
definitions = member.definitions.grep(Rubydex::MethodDefinition)
|
|
34
|
+
return nil if definitions.empty?
|
|
35
|
+
|
|
36
|
+
signature_shape(definitions.flat_map(&:signatures))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def signature_shape(signatures)
|
|
40
|
+
shapes = signatures.filter_map { |signature| shape_for(signature) }.uniq
|
|
41
|
+
shapes.one? ? shapes.first : nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def shape_for(signature)
|
|
45
|
+
return nil if signature.forward_parameter
|
|
46
|
+
|
|
47
|
+
min = signature.positional_parameters.size + signature.post_parameters.size
|
|
48
|
+
|
|
49
|
+
[min, maximum_positional(signature, min), keyword_parameters?(signature)]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def maximum_positional(signature, min)
|
|
53
|
+
return nil if signature.rest_positional_parameter
|
|
54
|
+
|
|
55
|
+
min + signature.optional_positional_parameters.size
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def keyword_parameters?(signature)
|
|
59
|
+
!signature.keyword_parameters.empty? ||
|
|
60
|
+
!signature.optional_keyword_parameters.empty? ||
|
|
61
|
+
!signature.rest_keyword_parameter.nil?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# The number of positional arguments the call passes, or nil when it
|
|
65
|
+
# cannot be determined statically (argument forwarding).
|
|
66
|
+
def positional_argument_count(node, callee_has_keywords)
|
|
67
|
+
arguments = node.arguments
|
|
68
|
+
return nil if forwards_arguments?(arguments)
|
|
69
|
+
|
|
70
|
+
arguments = arguments[0...-1] if arguments.last&.block_pass_type?
|
|
71
|
+
return arguments.size unless (keyword_hash = keyword_hash(arguments.last))
|
|
72
|
+
return nil if double_splat?(keyword_hash)
|
|
73
|
+
|
|
74
|
+
# A keyword-style hash passed to a method with no keyword parameters is
|
|
75
|
+
# received as a single positional hash argument.
|
|
76
|
+
callee_has_keywords ? arguments.size - 1 : arguments.size
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def forwards_arguments?(arguments)
|
|
80
|
+
arguments.any? do |argument|
|
|
81
|
+
argument.type?(:splat, :forwarded_args, :forwarded_restarg, :forwarded_kwrestarg)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def keyword_hash(node)
|
|
86
|
+
node if node&.hash_type? && !node.braces?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def double_splat?(hash_node)
|
|
90
|
+
hash_node.each_child_node.any?(&:kwsplat_type?)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -128,7 +128,13 @@ module RuboCop
|
|
|
128
128
|
# Additionally, the RFC2396_PARSER alias is only available on 3.4 for now.
|
|
129
129
|
# Extra info at https://github.com/ruby/uri/issues/118
|
|
130
130
|
parser = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER
|
|
131
|
-
|
|
131
|
+
schemes = config.for_cop('Layout/LineLength')['URISchemes']
|
|
132
|
+
regexp = parser.make_regexp(schemes)
|
|
133
|
+
|
|
134
|
+
# `make_regexp` in uri 1.1.0+ matches schemes case-insensitively, which makes
|
|
135
|
+
# constant paths like `Http::UploadedFile` look like URIs. Require the exact case
|
|
136
|
+
# given in `URISchemes`.
|
|
137
|
+
schemes ? /(?=#{Regexp.union(schemes)}:)#{regexp}/ : regexp
|
|
132
138
|
end
|
|
133
139
|
end
|
|
134
140
|
|
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
# Common functionality for checking whether an AST node/token is aligned
|
|
6
6
|
# with something on a preceding or following line
|
|
7
|
-
# rubocop:disable Metrics/ModuleLength
|
|
7
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
8
8
|
module PrecedingFollowingAlignment
|
|
9
9
|
# Tokens that end with an `=`, as well as `<<`, that can be aligned together:
|
|
10
10
|
# `=`, `==`, `===`, `!=`, `<=`, `>=`, `<<` and operator assignment (`+=`, etc).
|
|
@@ -69,7 +69,15 @@ module RuboCop
|
|
|
69
69
|
line = processed_source.lines[lineno]
|
|
70
70
|
index = line =~ /\S/
|
|
71
71
|
next unless index
|
|
72
|
-
|
|
72
|
+
|
|
73
|
+
if indent
|
|
74
|
+
# When searching for the nearest line with the same indentation,
|
|
75
|
+
# more deeply indented lines are nested content of the current group
|
|
76
|
+
# and are skipped, but a less deeply indented line ends the enclosing block:
|
|
77
|
+
# an alignment anchor beyond it would be coincidental.
|
|
78
|
+
break if index < indent
|
|
79
|
+
next if index > indent
|
|
80
|
+
end
|
|
73
81
|
|
|
74
82
|
return yield(range, line, lineno + 1)
|
|
75
83
|
end
|
|
@@ -174,20 +182,69 @@ module RuboCop
|
|
|
174
182
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
175
183
|
# rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength
|
|
176
184
|
def relevant_assignment_lines(line_range)
|
|
185
|
+
relevant_lines(line_range, interrupting_operator_lines) do |line_number|
|
|
186
|
+
assignment_lines.include?(line_number)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def interrupting_operator_lines
|
|
191
|
+
@interrupting_operator_lines ||=
|
|
192
|
+
processed_source.tokens.each_with_object(Set.new) do |token, lines|
|
|
193
|
+
next unless ASSIGNMENT_OR_COMPARISON_TOKENS.include?(token.type)
|
|
194
|
+
|
|
195
|
+
lines << token.line unless assignment_lines.include?(token.line)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def alignment_lines(line_number)
|
|
200
|
+
@alignment_lines_by_line ||= {}
|
|
201
|
+
return @alignment_lines_by_line[line_number] if @alignment_lines_by_line.key?(line_number)
|
|
202
|
+
|
|
203
|
+
lines = alignment_line_ranges(line_number).flatten.uniq.sort.freeze
|
|
204
|
+
|
|
205
|
+
lines.each { |line| @alignment_lines_by_line[line] = lines }
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def alignment_line_ranges(line_number)
|
|
209
|
+
last_line = processed_source.lines.length
|
|
210
|
+
|
|
211
|
+
[
|
|
212
|
+
relevant_lines(line_number.downto(1), definition_boundary_lines) do |line|
|
|
213
|
+
!aligned_comment_lines.include?(line)
|
|
214
|
+
end,
|
|
215
|
+
relevant_lines(line_number.upto(last_line), definition_boundary_lines) do |line|
|
|
216
|
+
!aligned_comment_lines.include?(line)
|
|
217
|
+
end
|
|
218
|
+
]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def definition_boundary_lines
|
|
222
|
+
@definition_boundary_lines ||= begin
|
|
223
|
+
nodes = processed_source.ast&.each_node(:any_def) || []
|
|
224
|
+
|
|
225
|
+
nodes.each_with_object(Set.new) do |node, lines|
|
|
226
|
+
lines << node.first_line << node.last_line
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def relevant_lines(line_range, boundary_lines = [])
|
|
177
232
|
result = []
|
|
178
|
-
|
|
233
|
+
original_line = line_range.first
|
|
234
|
+
original_line_indent = processed_source.line_indentation(original_line)
|
|
179
235
|
relevant_line_indent_at_level = true
|
|
180
236
|
|
|
181
237
|
line_range.each do |line_number|
|
|
182
238
|
current_line_indent = processed_source.line_indentation(line_number)
|
|
183
239
|
blank_line = processed_source.lines[line_number - 1].blank?
|
|
184
240
|
|
|
185
|
-
if (
|
|
241
|
+
if (line_number != original_line && boundary_lines.include?(line_number)) ||
|
|
242
|
+
(current_line_indent < original_line_indent && !blank_line) ||
|
|
186
243
|
(relevant_line_indent_at_level && blank_line)
|
|
187
244
|
break
|
|
188
245
|
end
|
|
189
246
|
|
|
190
|
-
result << line_number if
|
|
247
|
+
result << line_number if yield(line_number) &&
|
|
191
248
|
current_line_indent == original_line_indent
|
|
192
249
|
|
|
193
250
|
unless blank_line
|
|
@@ -214,6 +271,5 @@ module RuboCop
|
|
|
214
271
|
asgn_tokens.reject { |t| eqls_to_ignore.include?(t.begin_pos) }
|
|
215
272
|
end
|
|
216
273
|
end
|
|
217
|
-
# rubocop:enable Metrics/ModuleLength
|
|
218
274
|
end
|
|
219
275
|
end
|
|
@@ -116,14 +116,13 @@ module RuboCop
|
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
# rubocop:disable Metrics/ParameterLists
|
|
119
|
+
# rubocop:disable-next Metrics/ParameterLists
|
|
120
120
|
def final_pos(src, pos, increment, continuations, newlines, whitespace)
|
|
121
121
|
pos = move_pos(src, pos, increment, true, /[ \t]/)
|
|
122
122
|
pos = move_pos_str(src, pos, increment, continuations, "\\\n")
|
|
123
123
|
pos = move_pos(src, pos, increment, newlines, /\n/)
|
|
124
124
|
move_pos(src, pos, increment, whitespace, /\s/)
|
|
125
125
|
end
|
|
126
|
-
# rubocop:enable Metrics/ParameterLists
|
|
127
126
|
|
|
128
127
|
def move_pos(src, pos, step, condition, regexp)
|
|
129
128
|
offset = step == -1 ? -1 : 0
|
|
@@ -35,8 +35,14 @@ module RuboCop
|
|
|
35
35
|
condition.each_node.any?(&:lvasgn_type?)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# The rendered modifier form is compared against the bare maximum, not
|
|
39
|
+
# `acceptable_line_length?`: `Layout/LineLength`'s exemptions describe
|
|
40
|
+
# long lines the user tolerates, not permission to manufacture new ones,
|
|
41
|
+
# so collapsing to modifier form must never push a line past the maximum.
|
|
38
42
|
def modifier_fits_on_single_line?(node)
|
|
39
|
-
|
|
43
|
+
return true unless max_line_length
|
|
44
|
+
|
|
45
|
+
line_length(line_in_modifier_form(node)) <= max_line_length
|
|
40
46
|
end
|
|
41
47
|
|
|
42
48
|
def line_in_modifier_form(node)
|
|
@@ -46,12 +52,12 @@ module RuboCop
|
|
|
46
52
|
"#{code_before}#{to_modifier_form(node)}#{code_after(node)}"
|
|
47
53
|
end
|
|
48
54
|
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
+
# Whether an existing line is acceptable to `Layout/LineLength`,
|
|
56
|
+
# exemptions (the cop disabled at that line, an allowed pattern, an
|
|
57
|
+
# allowed cop directive, an allowed URI) included. Only for judging
|
|
58
|
+
# lines already in the source as too long - see
|
|
59
|
+
# `modifier_fits_on_single_line?` for why the exemptions must not apply
|
|
60
|
+
# when deciding whether a modifier line may be created.
|
|
55
61
|
def acceptable_line_length?(line, line_number)
|
|
56
62
|
return true unless max_line_length
|
|
57
63
|
return true if line_length(line) <= max_line_length
|
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
# Common methods shared by Style/TrailingCommaInArguments,
|
|
6
6
|
# Style/TrailingCommaInArrayLiteral and Style/TrailingCommaInHashLiteral
|
|
7
|
-
# rubocop:disable Metrics/ModuleLength
|
|
7
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
8
8
|
module TrailingComma
|
|
9
9
|
include ConfigurableEnforcedStyle
|
|
10
10
|
include RangeHelp
|
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
|
95
95
|
node.multiline? && !allowed_multiline_argument?(node)
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
# rubocop:disable Metrics/AbcSize
|
|
98
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
99
99
|
def method_name_and_arguments_on_same_line?(node)
|
|
100
100
|
return false if !node.call_type? || node.last_line != node.last_argument.last_line
|
|
101
101
|
return true if node.last_argument.hash_type? && node.last_argument.braces?
|
|
@@ -104,7 +104,6 @@ module RuboCop
|
|
|
104
104
|
|
|
105
105
|
line == node.last_argument.last_line
|
|
106
106
|
end
|
|
107
|
-
# rubocop:enable Metrics/AbcSize
|
|
108
107
|
|
|
109
108
|
# A single argument with the closing bracket on the same line as the end
|
|
110
109
|
# of the argument is not considered multiline, even if the argument
|
|
@@ -223,6 +222,5 @@ module RuboCop
|
|
|
223
222
|
false
|
|
224
223
|
end
|
|
225
224
|
end
|
|
226
|
-
# rubocop:enable Metrics/ModuleLength
|
|
227
225
|
end
|
|
228
226
|
end
|
data/lib/rubocop/cop/mixin.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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 mixins below
|
|
5
5
|
# Autoloads mixin modules included by cops. Mixins are autoloaded to reduce the number of
|
|
6
6
|
# requires because they're used only when the relevant cop class is loaded.
|
|
7
7
|
|
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
|
14
14
|
autoload :AllowedReceivers, "#{__dir__}/mixin/allowed_receivers"
|
|
15
15
|
autoload :ForbiddenIdentifiers, "#{__dir__}/mixin/forbidden_identifiers"
|
|
16
16
|
autoload :ForbiddenPattern, "#{__dir__}/mixin/forbidden_pattern"
|
|
17
|
-
autoload :AutoCorrector, "#{__dir__}/mixin/auto_corrector" # rubocop:todo Naming/InclusiveLanguage
|
|
17
|
+
autoload :AutoCorrector, "#{__dir__}/mixin/auto_corrector" # rubocop:todo Naming/InclusiveLanguage -- the file is named `auto_corrector.rb`
|
|
18
18
|
autoload :CheckAssignment, "#{__dir__}/mixin/check_assignment"
|
|
19
19
|
autoload :CheckLineBreakable, "#{__dir__}/mixin/check_line_breakable"
|
|
20
20
|
autoload :CheckSingleLineSuitability, "#{__dir__}/mixin/check_single_line_suitability"
|
|
@@ -41,6 +41,10 @@ module RuboCop
|
|
|
41
41
|
autoload :HashAlignmentStyles, "#{__dir__}/mixin/hash_alignment_styles"
|
|
42
42
|
autoload :HashSubset, "#{__dir__}/mixin/hash_subset"
|
|
43
43
|
autoload :HashTransformMethod, "#{__dir__}/mixin/hash_transform_method"
|
|
44
|
+
# Deprecated aliases of `AllowedMethods` and `AllowedPattern`, defined in those files.
|
|
45
|
+
autoload :IgnoredMethods, "#{__dir__}/mixin/allowed_methods"
|
|
46
|
+
autoload :IgnoredPattern, "#{__dir__}/mixin/allowed_pattern"
|
|
47
|
+
autoload :IndexedMethodArity, "#{__dir__}/mixin/indexed_method_arity"
|
|
44
48
|
autoload :IntegerNode, "#{__dir__}/mixin/integer_node"
|
|
45
49
|
autoload :Interpolation, "#{__dir__}/mixin/interpolation"
|
|
46
50
|
autoload :LineLengthHelp, "#{__dir__}/mixin/line_length_help"
|
|
@@ -33,6 +33,7 @@ module RuboCop
|
|
|
33
33
|
node.each_descendant(:lvar, :lvasgn) do |lvar|
|
|
34
34
|
lvar_location = lvar.loc.name
|
|
35
35
|
next unless lvar_location.source == arg.source
|
|
36
|
+
next if shadowed?(lvar, arg.source, node)
|
|
36
37
|
|
|
37
38
|
corrector.replace(lvar_location, 'other')
|
|
38
39
|
end
|
|
@@ -47,6 +48,21 @@ module RuboCop
|
|
|
47
48
|
|
|
48
49
|
!/\A[[:word:]]/.match?(name) || OP_LIKE_METHODS.include?(name)
|
|
49
50
|
end
|
|
51
|
+
|
|
52
|
+
# A reference is shadowed when an enclosing block within the method redeclares the
|
|
53
|
+
# parameter name (as a block parameter or block-local). Such a reference points to
|
|
54
|
+
# the block's variable, not the operator's parameter, so it must not be renamed.
|
|
55
|
+
def shadowed?(node, name, def_node)
|
|
56
|
+
node.each_ancestor(:block).any? do |block|
|
|
57
|
+
def_node.source_range.contains?(block.source_range) && redeclares?(block, name)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def redeclares?(block, name)
|
|
62
|
+
block.arguments.any? do |argument|
|
|
63
|
+
argument.respond_to?(:name) && argument.name.to_s == name
|
|
64
|
+
end
|
|
65
|
+
end
|
|
50
66
|
end
|
|
51
67
|
end
|
|
52
68
|
end
|
|
@@ -62,7 +62,10 @@ module RuboCop
|
|
|
62
62
|
MSG = 'Use %<style>s block forwarding.'
|
|
63
63
|
|
|
64
64
|
def self.autocorrect_incompatible_with
|
|
65
|
-
[
|
|
65
|
+
[
|
|
66
|
+
Lint::AmbiguousOperator, Style::ArgumentsForwarding,
|
|
67
|
+
Style::ExplicitBlockArgument, Style::MethodDefParentheses
|
|
68
|
+
]
|
|
66
69
|
end
|
|
67
70
|
|
|
68
71
|
def on_def(node)
|
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
|
38
38
|
class BlockParameterName < Base
|
|
39
39
|
include UncommunicativeName
|
|
40
40
|
|
|
41
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
41
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler -- there are no parameter names to check
|
|
42
42
|
return unless node.arguments?
|
|
43
43
|
|
|
44
44
|
check(node, node.arguments)
|
|
@@ -167,7 +167,7 @@ module RuboCop
|
|
|
167
167
|
PATTERN
|
|
168
168
|
|
|
169
169
|
# rubocop:disable Metrics/AbcSize
|
|
170
|
-
# rubocop:disable Metrics/MethodLength
|
|
170
|
+
# rubocop:disable-next Metrics/MethodLength
|
|
171
171
|
def on_or_asgn(node)
|
|
172
172
|
lhs = node.lhs
|
|
173
173
|
return unless lhs.ivasgn_type?
|
|
@@ -192,7 +192,6 @@ module RuboCop
|
|
|
192
192
|
corrector.replace(lhs.loc.name, "@#{suggested_var}")
|
|
193
193
|
end
|
|
194
194
|
end
|
|
195
|
-
# rubocop:enable Metrics/MethodLength
|
|
196
195
|
# rubocop:enable Metrics/AbcSize
|
|
197
196
|
|
|
198
197
|
# @!method defined_memoized?(node, ivar)
|
|
@@ -203,7 +202,7 @@ module RuboCop
|
|
|
203
202
|
$(ivasgn %1 _))
|
|
204
203
|
PATTERN
|
|
205
204
|
|
|
206
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
205
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
|
|
207
206
|
def on_defined?(node)
|
|
208
207
|
arg = node.first_argument
|
|
209
208
|
return false unless arg.ivar_type?
|
|
@@ -233,7 +232,6 @@ module RuboCop
|
|
|
233
232
|
end
|
|
234
233
|
end
|
|
235
234
|
end
|
|
236
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
237
235
|
|
|
238
236
|
private
|
|
239
237
|
|
|
@@ -105,6 +105,10 @@ module RuboCop
|
|
|
105
105
|
|
|
106
106
|
MSG = 'Use %<style>s for method names.'
|
|
107
107
|
MSG_FORBIDDEN = '`%<identifier>s` is forbidden, use another method name instead.'
|
|
108
|
+
RESTRICT_ON_SEND = %i[
|
|
109
|
+
define_method define_singleton_method new define alias_method
|
|
110
|
+
attr attr_reader attr_writer attr_accessor
|
|
111
|
+
].freeze
|
|
108
112
|
|
|
109
113
|
OPERATOR_METHODS = %i[| ^ & <=> == === =~ > >= < <= << >> + - * /
|
|
110
114
|
% ** ~ +@ -@ !@ ~@ [] []= ! != !~ `].to_set.freeze
|
|
@@ -209,7 +213,7 @@ module RuboCop
|
|
|
209
213
|
forbidden_identifier?(name) || forbidden_pattern?(name)
|
|
210
214
|
end
|
|
211
215
|
|
|
212
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
216
|
+
# rubocop:disable-next Metrics/MethodLength, Metrics/AbcSize
|
|
213
217
|
def register_forbidden_name(node)
|
|
214
218
|
if node.any_def_type?
|
|
215
219
|
name_node = node.loc.name
|
|
@@ -227,7 +231,6 @@ module RuboCop
|
|
|
227
231
|
message = format(MSG_FORBIDDEN, identifier: method_name)
|
|
228
232
|
add_offense(name_node, message: message)
|
|
229
233
|
end
|
|
230
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
231
234
|
|
|
232
235
|
def attr_name(name_item)
|
|
233
236
|
sym_name(name_item) || str_name(name_item)
|
|
@@ -118,7 +118,7 @@ module RuboCop
|
|
|
118
118
|
|
|
119
119
|
# Returns the reassignment node once the exception variable is reassigned (a truthy
|
|
120
120
|
# signal to stop correcting later references), or `nil` when no reassignment is found.
|
|
121
|
-
# rubocop:disable Metrics/MethodLength
|
|
121
|
+
# rubocop:disable-next Metrics/MethodLength
|
|
122
122
|
def correct_node(corrector, node, offending_name, preferred_name)
|
|
123
123
|
return unless node
|
|
124
124
|
|
|
@@ -141,7 +141,6 @@ module RuboCop
|
|
|
141
141
|
end
|
|
142
142
|
nil
|
|
143
143
|
end
|
|
144
|
-
# rubocop:enable Metrics/MethodLength
|
|
145
144
|
|
|
146
145
|
# If the exception variable is reassigned, that assignment needs to be corrected.
|
|
147
146
|
# Further `lvar` nodes will not be corrected though since they now refer to a
|
data/lib/rubocop/cop/offense.rb
CHANGED
|
@@ -86,9 +86,19 @@ module RuboCop
|
|
|
86
86
|
|
|
87
87
|
NO_LOCATION = PseudoSourceRange.new(1, 0, '', 0, 0).freeze
|
|
88
88
|
|
|
89
|
+
# @api public
|
|
90
|
+
#
|
|
91
|
+
# @!attribute [r] justification
|
|
92
|
+
#
|
|
93
|
+
# @return [String, nil]
|
|
94
|
+
# the reason given on the directive that suppressed this offense
|
|
95
|
+
# (the text after `--`), or `nil` when the offense is not suppressed
|
|
96
|
+
# or the directive carries no reason
|
|
97
|
+
attr_reader :justification
|
|
98
|
+
|
|
89
99
|
# @api private
|
|
90
100
|
def initialize(severity, location, message, cop_name, # rubocop:disable Metrics/ParameterLists
|
|
91
|
-
status = :uncorrected, corrector = nil)
|
|
101
|
+
status = :uncorrected, corrector = nil, justification: nil)
|
|
92
102
|
@severity = RuboCop::Cop::Severity.new(severity)
|
|
93
103
|
@location = location
|
|
94
104
|
|
|
@@ -101,15 +111,16 @@ module RuboCop
|
|
|
101
111
|
@cop_name = cop_name.freeze
|
|
102
112
|
@status = status
|
|
103
113
|
@corrector = corrector
|
|
114
|
+
@justification = justification.freeze
|
|
104
115
|
freeze
|
|
105
116
|
end
|
|
106
117
|
|
|
107
118
|
def marshal_dump
|
|
108
|
-
[@severity, @location, @message, @cop_name, @status]
|
|
119
|
+
[@severity, @location, @message, @cop_name, @status, @justification]
|
|
109
120
|
end
|
|
110
121
|
|
|
111
122
|
def marshal_load(array)
|
|
112
|
-
@severity, @location, @message, @cop_name, @status = array
|
|
123
|
+
@severity, @location, @message, @cop_name, @status, @justification = array
|
|
113
124
|
@line = @location.line
|
|
114
125
|
@column = @location.column
|
|
115
126
|
end
|
|
@@ -121,8 +132,10 @@ module RuboCop
|
|
|
121
132
|
# @return [Boolean]
|
|
122
133
|
# whether this offense can be automatically corrected via autocorrect.
|
|
123
134
|
# This includes todo comments, for example when requested with `--disable-uncorrectable`.
|
|
135
|
+
# An offense suppressed by a directive comment is not correctable -
|
|
136
|
+
# autocorrect will not touch it.
|
|
124
137
|
def correctable?
|
|
125
|
-
@status != :unsupported
|
|
138
|
+
@status != :unsupported && @status != :disabled
|
|
126
139
|
end
|
|
127
140
|
|
|
128
141
|
# @api public
|
|
@@ -223,6 +236,16 @@ module RuboCop
|
|
|
223
236
|
column + 1
|
|
224
237
|
end
|
|
225
238
|
|
|
239
|
+
# @api private
|
|
240
|
+
#
|
|
241
|
+
# The minimum value of `real_column` is 1, so the minimum value of
|
|
242
|
+
# `real_last_column` is also 1. A non-zero `last_column` is used as is,
|
|
243
|
+
# because the 0-based end-exclusive column is the same as the 1-based
|
|
244
|
+
# column of the last character.
|
|
245
|
+
def real_last_column
|
|
246
|
+
last_column.zero? ? 1 : last_column
|
|
247
|
+
end
|
|
248
|
+
|
|
226
249
|
# @api public
|
|
227
250
|
#
|
|
228
251
|
# @return [Boolean]
|
data/lib/rubocop/cop/registry.rb
CHANGED
|
@@ -23,8 +23,8 @@ module RuboCop
|
|
|
23
23
|
global.without_department(:Test).cops
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def self.qualified_cop_name(name, origin, warn: true)
|
|
27
|
-
global.qualified_cop_name(name, origin, warn: warn)
|
|
26
|
+
def self.qualified_cop_name(name, origin, warn: true, correct_namespace: true)
|
|
27
|
+
global.qualified_cop_name(name, origin, warn: warn, correct_namespace: correct_namespace)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# Changes momentarily the global registry
|
|
@@ -171,11 +171,19 @@ module RuboCop
|
|
|
171
171
|
# @note Emits a warning if the provided name has an incorrect namespace
|
|
172
172
|
#
|
|
173
173
|
# @return [String] Qualified cop name
|
|
174
|
-
def qualified_cop_name(name, path, warn: true)
|
|
174
|
+
def qualified_cop_name(name, path, warn: true, correct_namespace: true)
|
|
175
175
|
badge = Badge.parse(name)
|
|
176
176
|
print_department_missing_warning(name, path) if warn && department_missing?(badge, name)
|
|
177
177
|
return name if registered?(badge)
|
|
178
|
+
# A name qualified with the wrong department is returned as is when
|
|
179
|
+
# namespace correction is not wanted, so the caller can surface the
|
|
180
|
+
# mistake instead of silently acting on the corrected name.
|
|
181
|
+
return name if badge.qualified? && !correct_namespace
|
|
178
182
|
|
|
183
|
+
resolve_cop_name(badge, name, path, warn)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def resolve_cop_name(badge, name, path, warn)
|
|
179
187
|
potential_badges = qualify_badge(badge)
|
|
180
188
|
|
|
181
189
|
case potential_badges.size
|
|
@@ -272,6 +280,12 @@ module RuboCop
|
|
|
272
280
|
config.enabled_new_cop?(cop_name)
|
|
273
281
|
end
|
|
274
282
|
|
|
283
|
+
# Preview cops are opt-in and stay silent otherwise, so unlike pending cops
|
|
284
|
+
# they are never reported as needing a decision.
|
|
285
|
+
def enabled_preview_cop?(cop_cfg, config)
|
|
286
|
+
cop_cfg.fetch('Enabled') == 'preview' && config.preview?(@options)
|
|
287
|
+
end
|
|
288
|
+
|
|
275
289
|
def names
|
|
276
290
|
clear_enrollment_queue
|
|
277
291
|
@cops_by_badge.keys.map(&:to_s)
|
|
@@ -325,10 +339,33 @@ module RuboCop
|
|
|
325
339
|
cop ? [cop] : cops_for_department(directive)
|
|
326
340
|
end
|
|
327
341
|
|
|
342
|
+
# Loads all cops that are registered for lazy loading. Useful when lazily registered cops
|
|
343
|
+
# must not outlive the current global registry, e.g. before a temporary global registry is
|
|
344
|
+
# discarded in tests.
|
|
345
|
+
#
|
|
346
|
+
# @api private
|
|
347
|
+
def load_all_lazy_cops
|
|
348
|
+
# Take a snapshot because loading a cop can load (and thereby register)
|
|
349
|
+
# another lazy-loaded cop, e.g. its superclass.
|
|
350
|
+
badges = @cops_by_badge.keys
|
|
351
|
+
|
|
352
|
+
badges.each do |badge|
|
|
353
|
+
load_lazy_cop(badge) if @cops_by_badge[badge].is_a?(String)
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
328
357
|
def freeze
|
|
329
358
|
clear_enrollment_queue
|
|
330
359
|
load_all_lazy_cops
|
|
331
360
|
unqualified_cop_names # build cache
|
|
361
|
+
|
|
362
|
+
# Freeze the structural collections as well, so that a cop class defined after
|
|
363
|
+
# the freeze fails fast at its `enlist`/`lazy_load` call site instead of corrupting
|
|
364
|
+
# the registry and failing much later.
|
|
365
|
+
@cops_by_badge.freeze
|
|
366
|
+
@departments.freeze
|
|
367
|
+
@enrollment_queue.freeze
|
|
368
|
+
|
|
332
369
|
super
|
|
333
370
|
end
|
|
334
371
|
|
|
@@ -389,7 +426,9 @@ module RuboCop
|
|
|
389
426
|
# caching which expects cop names or cop classes as keys.
|
|
390
427
|
cfg = config.for_cop(cop_name)
|
|
391
428
|
|
|
392
|
-
cop_enabled = cfg.fetch('Enabled') == true ||
|
|
429
|
+
cop_enabled = cfg.fetch('Enabled') == true ||
|
|
430
|
+
enabled_pending_cop?(cfg, config, cop_name) ||
|
|
431
|
+
enabled_preview_cop?(cfg, config)
|
|
393
432
|
|
|
394
433
|
if options.fetch(:safe, false)
|
|
395
434
|
cop_enabled && cfg.fetch('Safe', true)
|
|
@@ -398,13 +437,6 @@ module RuboCop
|
|
|
398
437
|
end
|
|
399
438
|
end
|
|
400
439
|
|
|
401
|
-
def load_all_lazy_cops
|
|
402
|
-
# Take a snapshot because loading a cop can load (and thereby register)
|
|
403
|
-
# another lazy-loaded cop, e.g. its superclass.
|
|
404
|
-
badges = @cops_by_badge.keys
|
|
405
|
-
badges.each { |badge| load_lazy_cop(badge) if @cops_by_badge[badge].is_a?(String) }
|
|
406
|
-
end
|
|
407
|
-
|
|
408
440
|
# @return [Class, nil] the loaded cop class, or nil if the cop excluded
|
|
409
441
|
# itself from the registry while being loaded
|
|
410
442
|
def load_lazy_cop(badge)
|
data/lib/rubocop/cop/severity.rb
CHANGED
|
@@ -21,6 +21,18 @@ module RuboCop
|
|
|
21
21
|
# any of `:info`, `:refactor`, `:convention`, `:warning`, `:error` or `:fatal`.
|
|
22
22
|
attr_reader :name
|
|
23
23
|
|
|
24
|
+
# The lowest severity that makes a run fail: `--fail-level` when given,
|
|
25
|
+
# otherwise `AllCops: FailLevel`. `autocorrect` is a pseudo level on the
|
|
26
|
+
# command line that gates on corrections instead, so it leaves the
|
|
27
|
+
# threshold at the configured one.
|
|
28
|
+
def self.minimum_to_fail(options, config)
|
|
29
|
+
name = options[:fail_level]
|
|
30
|
+
if name.nil? || name == :autocorrect
|
|
31
|
+
name = (config&.for_all_cops&.[]('FailLevel') || :refactor).to_sym
|
|
32
|
+
end
|
|
33
|
+
new(name)
|
|
34
|
+
end
|
|
35
|
+
|
|
24
36
|
def self.name_from_code(code)
|
|
25
37
|
name = code.to_sym
|
|
26
38
|
CODE_TABLE[name] || name
|