rubocop 1.89.0 → 1.90.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 +74 -7
- data/exe/rubocop +1 -1
- data/lib/rubocop/cached_data.rb +7 -2
- data/lib/rubocop/cli/command/execute_runner.rb +31 -0
- data/lib/rubocop/cli.rb +2 -4
- data/lib/rubocop/comment_config/directive_range.rb +32 -0
- data/lib/rubocop/comment_config/disable_next.rb +97 -0
- data/lib/rubocop/comment_config.rb +46 -30
- data/lib/rubocop/config.rb +23 -5
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +1 -2
- data/lib/rubocop/config_validator.rb +1 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +8 -0
- data/lib/rubocop/cop/base.rb +34 -2
- data/lib/rubocop/cop/corrector.rb +3 -3
- 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/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/class_structure.rb +102 -26
- 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/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/line_continuation_spacing.rb +1 -2
- data/lib/rubocop/cop/layout/line_length.rb +1 -2
- 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_operators.rb +7 -0
- 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 +89 -0
- data/lib/rubocop/cop/lint/constant_reassignment.rb +17 -11
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -8
- data/lib/rubocop/cop/lint/deprecated_reference.rb +11 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +112 -14
- 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 +3 -6
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +3 -6
- 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/out_of_range_regexp_ref.rb +15 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +98 -19
- 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 +2 -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/comments_help.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -2
- data/lib/rubocop/cop/mixin/hash_subset.rb +1 -2
- 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 +51 -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 +4 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +16 -0
- 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 +34 -10
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -6
- 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 +2 -4
- 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 +1 -2
- data/lib/rubocop/cop/style/copyright.rb +1 -2
- data/lib/rubocop/cop/style/directive_scope.rb +171 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +36 -10
- data/lib/rubocop/cop/style/empty_case_condition.rb +1 -2
- data/lib/rubocop/cop/style/format_string_token.rb +1 -2
- data/lib/rubocop/cop/style/guard_clause.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
- 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/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_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/nil_comparison.rb +1 -2
- 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/redundant_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +1 -2
- data/lib/rubocop/cop/style/redundant_each.rb +1 -2
- data/lib/rubocop/cop/style/redundant_format.rb +2 -4
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -2
- 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_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +1 -2
- 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/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/yoda_condition.rb +1 -2
- data/lib/rubocop/cop/style.rb +2 -0
- data/lib/rubocop/cop/team.rb +11 -3
- data/lib/rubocop/cop/util.rb +2 -4
- data/lib/rubocop/cop/variable_force/variable.rb +1 -2
- data/lib/rubocop/cops_documentation_generator.rb +3 -6
- data/lib/rubocop/directive_comment.rb +37 -3
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- 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/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/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +4 -8
- data/lib/rubocop/lsp/routes.rb +48 -19
- data/lib/rubocop/mcp/server.rb +1 -2
- data/lib/rubocop/options.rb +10 -6
- data/lib/rubocop/path_util.rb +1 -2
- data/lib/rubocop/plugin/configuration_integrator.rb +6 -3
- data/lib/rubocop/rake_task.rb +1 -2
- data/lib/rubocop/rspec/expect_offense.rb +2 -4
- data/lib/rubocop/rspec/shared_contexts.rb +4 -2
- data/lib/rubocop/runner.rb +26 -23
- 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/version.rb +3 -5
- data/lib/rubocop.rb +3 -0
- data/lib/ruby_lsp/rubocop/addon.rb +1 -2
- metadata +13 -5
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
|
49
49
|
|
|
50
50
|
private
|
|
51
51
|
|
|
52
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
52
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
53
53
|
def complexity_score_for(node)
|
|
54
54
|
case node.type
|
|
55
55
|
when :case
|
|
@@ -74,7 +74,6 @@ module RuboCop
|
|
|
74
74
|
super
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
78
77
|
|
|
79
78
|
def simple_in_pattern?(in_pattern_node)
|
|
80
79
|
# `in_pattern_node.children[1]` is the guard (`if`/`unless`), or `nil`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Lint/RedundantCopDisableDirective needs to be disabled so as
|
|
4
4
|
# to be able to provide examples of rubocop:disable comments.
|
|
5
|
-
# rubocop:disable Lint/RedundantCopDisableDirective
|
|
5
|
+
# rubocop:disable-next Lint/RedundantCopDisableDirective
|
|
6
6
|
module RuboCop
|
|
7
7
|
module Cop
|
|
8
8
|
module Migration
|
|
@@ -85,4 +85,3 @@ module RuboCop
|
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
|
-
# rubocop:enable Lint/RedundantCopDisableDirective
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
# Returns the end line of a node, which might be a comment and not part of the AST
|
|
65
65
|
# End line is considered either the line at which another node starts, or
|
|
66
66
|
# the line at which the parent node ends.
|
|
67
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
67
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
68
68
|
def find_end_line(node)
|
|
69
69
|
if node.if_type?
|
|
70
70
|
if node.else?
|
|
@@ -89,7 +89,6 @@ module RuboCop
|
|
|
89
89
|
end
|
|
90
90
|
end || node.loc.end.line
|
|
91
91
|
end
|
|
92
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
93
92
|
end
|
|
94
93
|
end
|
|
95
94
|
end
|
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
|
25
25
|
end
|
|
26
26
|
private_constant :SYMBOL_TO_STRING_CACHE
|
|
27
27
|
|
|
28
|
-
# rubocop:disable Metrics
|
|
28
|
+
# rubocop:disable-next Metrics
|
|
29
29
|
def style_detected(detected)
|
|
30
30
|
return if no_acceptable_style?
|
|
31
31
|
|
|
@@ -51,7 +51,6 @@ module RuboCop
|
|
|
51
51
|
config_to_allow_offenses[style_parameter_name] = updated_list.first
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
|
-
# rubocop:enable Metrics
|
|
55
54
|
|
|
56
55
|
def no_acceptable_style?
|
|
57
56
|
config_to_allow_offenses['Enabled'] == false
|
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
|
117
117
|
use_modifier_form_without_parenthesized_method_call?(method_dispatch_node)
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
120
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
121
121
|
def def_node_that_require_parentheses(node)
|
|
122
122
|
last_pair = node.parent.pairs.last
|
|
123
123
|
return unless last_pair.key.source == last_pair.value.source
|
|
@@ -131,7 +131,6 @@ module RuboCop
|
|
|
131
131
|
|
|
132
132
|
DefNode.new(def_node) unless def_node && def_node.arguments.empty?
|
|
133
133
|
end
|
|
134
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
135
134
|
|
|
136
135
|
def find_ancestor_method_dispatch_node(node)
|
|
137
136
|
return unless (ancestor = node.parent.parent)
|
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
|
5
5
|
# Common functionality for Style/HashExcept and Style/HashSlice cops.
|
|
6
6
|
# It registers an offense on methods with blocks that are equivalent
|
|
7
7
|
# to Hash#except or Hash#slice.
|
|
8
|
-
# rubocop:disable Metrics/ModuleLength
|
|
8
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
9
9
|
module HashSubset
|
|
10
10
|
include RangeHelp
|
|
11
11
|
extend NodePattern::Macros
|
|
@@ -206,6 +206,5 @@ module RuboCop
|
|
|
206
206
|
range_between(node.loc.selector.begin_pos, node.parent.loc.end.end_pos)
|
|
207
207
|
end
|
|
208
208
|
end
|
|
209
|
-
# rubocop:enable Metrics/ModuleLength
|
|
210
209
|
end
|
|
211
210
|
end
|
|
@@ -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,58 @@ 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) { |line_number| assignment_lines.include?(line_number) }
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def alignment_lines(line_number)
|
|
189
|
+
@alignment_lines_by_line ||= {}
|
|
190
|
+
return @alignment_lines_by_line[line_number] if @alignment_lines_by_line.key?(line_number)
|
|
191
|
+
|
|
192
|
+
lines = alignment_line_ranges(line_number).flatten.uniq.sort.freeze
|
|
193
|
+
|
|
194
|
+
lines.each { |line| @alignment_lines_by_line[line] = lines }
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def alignment_line_ranges(line_number)
|
|
198
|
+
last_line = processed_source.lines.length
|
|
199
|
+
|
|
200
|
+
[
|
|
201
|
+
relevant_lines(line_number.downto(1), definition_boundary_lines) do |line|
|
|
202
|
+
!aligned_comment_lines.include?(line)
|
|
203
|
+
end,
|
|
204
|
+
relevant_lines(line_number.upto(last_line), definition_boundary_lines) do |line|
|
|
205
|
+
!aligned_comment_lines.include?(line)
|
|
206
|
+
end
|
|
207
|
+
]
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def definition_boundary_lines
|
|
211
|
+
@definition_boundary_lines ||= begin
|
|
212
|
+
nodes = processed_source.ast&.each_node(:any_def) || []
|
|
213
|
+
|
|
214
|
+
nodes.each_with_object(Set.new) do |node, lines|
|
|
215
|
+
lines << node.first_line << node.last_line
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def relevant_lines(line_range, boundary_lines = [])
|
|
177
221
|
result = []
|
|
178
|
-
|
|
222
|
+
original_line = line_range.first
|
|
223
|
+
original_line_indent = processed_source.line_indentation(original_line)
|
|
179
224
|
relevant_line_indent_at_level = true
|
|
180
225
|
|
|
181
226
|
line_range.each do |line_number|
|
|
182
227
|
current_line_indent = processed_source.line_indentation(line_number)
|
|
183
228
|
blank_line = processed_source.lines[line_number - 1].blank?
|
|
184
229
|
|
|
185
|
-
if (
|
|
230
|
+
if (line_number != original_line && boundary_lines.include?(line_number)) ||
|
|
231
|
+
(current_line_indent < original_line_indent && !blank_line) ||
|
|
186
232
|
(relevant_line_indent_at_level && blank_line)
|
|
187
233
|
break
|
|
188
234
|
end
|
|
189
235
|
|
|
190
|
-
result << line_number if
|
|
236
|
+
result << line_number if yield(line_number) &&
|
|
191
237
|
current_line_indent == original_line_indent
|
|
192
238
|
|
|
193
239
|
unless blank_line
|
|
@@ -214,6 +260,5 @@ module RuboCop
|
|
|
214
260
|
asgn_tokens.reject { |t| eqls_to_ignore.include?(t.begin_pos) }
|
|
215
261
|
end
|
|
216
262
|
end
|
|
217
|
-
# rubocop:enable Metrics/ModuleLength
|
|
218
263
|
end
|
|
219
264
|
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
|
@@ -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
|
|
@@ -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
|
|
@@ -325,10 +333,33 @@ module RuboCop
|
|
|
325
333
|
cop ? [cop] : cops_for_department(directive)
|
|
326
334
|
end
|
|
327
335
|
|
|
336
|
+
# Loads all cops that are registered for lazy loading. Useful when lazily registered cops
|
|
337
|
+
# must not outlive the current global registry, e.g. before a temporary global registry is
|
|
338
|
+
# discarded in tests.
|
|
339
|
+
#
|
|
340
|
+
# @api private
|
|
341
|
+
def load_all_lazy_cops
|
|
342
|
+
# Take a snapshot because loading a cop can load (and thereby register)
|
|
343
|
+
# another lazy-loaded cop, e.g. its superclass.
|
|
344
|
+
badges = @cops_by_badge.keys
|
|
345
|
+
|
|
346
|
+
badges.each do |badge|
|
|
347
|
+
load_lazy_cop(badge) if @cops_by_badge[badge].is_a?(String)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
328
351
|
def freeze
|
|
329
352
|
clear_enrollment_queue
|
|
330
353
|
load_all_lazy_cops
|
|
331
354
|
unqualified_cop_names # build cache
|
|
355
|
+
|
|
356
|
+
# Freeze the structural collections as well, so that a cop class defined after
|
|
357
|
+
# the freeze fails fast at its `enlist`/`lazy_load` call site instead of corrupting
|
|
358
|
+
# the registry and failing much later.
|
|
359
|
+
@cops_by_badge.freeze
|
|
360
|
+
@departments.freeze
|
|
361
|
+
@enrollment_queue.freeze
|
|
362
|
+
|
|
332
363
|
super
|
|
333
364
|
end
|
|
334
365
|
|
|
@@ -398,13 +429,6 @@ module RuboCop
|
|
|
398
429
|
end
|
|
399
430
|
end
|
|
400
431
|
|
|
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
432
|
# @return [Class, nil] the loaded cop class, or nil if the cop excluded
|
|
409
433
|
# itself from the registry while being loaded
|
|
410
434
|
def load_lazy_cop(badge)
|