rubocop 0.85.0 → 0.88.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 +25 -17
- data/bin/rubocop-profile +31 -0
- data/config/default.yml +132 -11
- data/lib/rubocop.rb +17 -1
- data/lib/rubocop/cli.rb +2 -4
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +42 -7
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/show_cops.rb +1 -1
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_loader.rb +39 -67
- data/lib/rubocop/config_loader_resolver.rb +1 -1
- data/lib/rubocop/config_obsoletion.rb +0 -1
- data/lib/rubocop/config_store.rb +4 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +14 -24
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +407 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +10 -20
- data/lib/rubocop/cop/commissioner.rb +48 -50
- data/lib/rubocop/cop/cop.rb +91 -235
- data/lib/rubocop/cop/corrector.rb +38 -115
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +26 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +7 -2
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +11 -14
- data/lib/rubocop/cop/layout/case_indentation.rb +18 -19
- data/lib/rubocop/cop/layout/class_structure.rb +2 -37
- data/lib/rubocop/cop/layout/comment_indentation.rb +3 -3
- data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +3 -8
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/end_of_line.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +2 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +17 -7
- data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +22 -27
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +27 -68
- data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +4 -3
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +49 -0
- data/lib/rubocop/cop/legacy/corrector.rb +29 -0
- data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -4
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +8 -2
- data/lib/rubocop/cop/lint/duplicate_elsif_condition.rb +39 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +38 -2
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +3 -2
- data/lib/rubocop/cop/lint/interpolation_check.rb +13 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +11 -1
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +8 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +14 -20
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +69 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -3
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/raise_exception.rb +12 -4
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +31 -25
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +2 -2
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +9 -1
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +11 -26
- data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +22 -0
- data/lib/rubocop/cop/metrics/class_length.rb +25 -2
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +35 -3
- data/lib/rubocop/cop/metrics/method_length.rb +23 -0
- data/lib/rubocop/cop/metrics/module_length.rb +25 -2
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +129 -0
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
- data/lib/rubocop/cop/mixin/allowed_methods.rb +19 -0
- data/lib/rubocop/cop/mixin/auto_corrector.rb +12 -0
- data/lib/rubocop/cop/mixin/code_length.rb +4 -0
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -1
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/nil_methods.rb +3 -5
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +6 -1
- data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +1 -1
- data/lib/rubocop/cop/mixin/regexp_literal_help.rb +27 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -3
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/surrounding_space.rb +10 -5
- data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -13
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +6 -4
- data/lib/rubocop/cop/mixin/visibility_help.rb +50 -0
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +27 -4
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +3 -3
- data/lib/rubocop/cop/naming/file_name.rb +1 -3
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +3 -5
- data/lib/rubocop/cop/naming/variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/variable_number.rb +1 -1
- data/lib/rubocop/cop/offense.rb +16 -2
- data/lib/rubocop/cop/registry.rb +62 -7
- data/lib/rubocop/cop/style/accessor_grouping.rb +147 -0
- data/lib/rubocop/cop/style/array_coercion.rb +63 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +3 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -1
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +146 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -4
- data/lib/rubocop/cop/style/case_like_if.rb +217 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_vars.rb +21 -0
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/copyright.rb +3 -3
- data/lib/rubocop/cop/style/date_time.rb +1 -1
- data/lib/rubocop/cop/style/dir.rb +2 -2
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +2 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +8 -6
- data/lib/rubocop/cop/style/empty_literal.rb +5 -5
- data/lib/rubocop/cop/style/encoding.rb +1 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +8 -10
- data/lib/rubocop/cop/style/float_division.rb +7 -10
- data/lib/rubocop/cop/style/format_string_token.rb +5 -5
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +62 -0
- data/lib/rubocop/cop/style/hash_like_case.rb +76 -0
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +11 -11
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +1 -11
- data/lib/rubocop/cop/style/multiline_block_chain.rb +10 -1
- data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -6
- data/lib/rubocop/cop/style/mutable_constant.rb +4 -4
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -5
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
- data/lib/rubocop/cop/style/next.rb +2 -2
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +3 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -3
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +1 -1
- data/lib/rubocop/cop/style/random_with_offset.rb +4 -10
- data/lib/rubocop/cop/style/redundant_assignment.rb +117 -0
- data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +14 -10
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +122 -0
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +50 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +8 -2
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +4 -3
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +14 -23
- data/lib/rubocop/cop/style/redundant_self.rb +6 -9
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -2
- data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/signal_exception.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -2
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +23 -2
- data/lib/rubocop/cop/style/symbol_array.rb +5 -5
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +9 -32
- data/lib/rubocop/cop/style/trivial_accessors.rb +8 -7
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +2 -2
- data/lib/rubocop/cop/team.rb +105 -81
- data/lib/rubocop/cop/util.rb +2 -2
- data/lib/rubocop/cop/utils/format_string.rb +19 -2
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/file_finder.rb +12 -12
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/name_similarity.rb +7 -3
- data/lib/rubocop/options.rb +15 -8
- data/lib/rubocop/path_util.rb +4 -19
- data/lib/rubocop/platform.rb +1 -1
- data/lib/rubocop/rake_task.rb +6 -9
- data/lib/rubocop/result_cache.rb +12 -8
- data/lib/rubocop/rspec/cop_helper.rb +4 -4
- data/lib/rubocop/rspec/expect_offense.rb +65 -21
- data/lib/rubocop/rspec/shared_contexts.rb +19 -16
- data/lib/rubocop/runner.rb +34 -33
- data/lib/rubocop/target_finder.rb +3 -3
- data/lib/rubocop/target_ruby.rb +2 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +34 -9
- data/lib/rubocop/cop/mixin/classish_length.rb +0 -37
@@ -18,7 +18,7 @@ module RuboCop
|
|
18
18
|
'name its argument `other`.'
|
19
19
|
|
20
20
|
OP_LIKE_METHODS = %i[eql? equal?].freeze
|
21
|
-
|
21
|
+
EXCLUDED = %i[+@ -@ [] []= << === `].freeze
|
22
22
|
|
23
23
|
def_node_matcher :op_method_candidate?, <<~PATTERN
|
24
24
|
(def [#op_method? $_] (args $(arg [!:other !:_other])) _)
|
@@ -33,9 +33,9 @@ module RuboCop
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def op_method?(name)
|
36
|
-
return false if
|
36
|
+
return false if EXCLUDED.include?(name)
|
37
37
|
|
38
|
-
|
38
|
+
!/\A\w/.match?(name) || OP_LIKE_METHODS.include?(name)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -123,10 +123,9 @@ module RuboCop
|
|
123
123
|
# special handling for Action Pack Variants file names like
|
124
124
|
# some_file.xlsx+mobile.axlsx
|
125
125
|
basename = basename.sub('+', '_')
|
126
|
-
basename
|
126
|
+
basename.match?(regex || SNAKE_CASE)
|
127
127
|
end
|
128
128
|
|
129
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
130
129
|
def find_class_or_module(node, namespace)
|
131
130
|
return nil unless node
|
132
131
|
|
@@ -145,7 +144,6 @@ module RuboCop
|
|
145
144
|
|
146
145
|
nil
|
147
146
|
end
|
148
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
149
147
|
|
150
148
|
def match_namespace(node, namespace, expected)
|
151
149
|
match_partial = partial_matcher!(expected)
|
@@ -28,6 +28,8 @@ module RuboCop
|
|
28
28
|
# def value?
|
29
29
|
# end
|
30
30
|
class PredicateName < Cop
|
31
|
+
include AllowedMethods
|
32
|
+
|
31
33
|
def_node_matcher :dynamic_method_define, <<~PATTERN
|
32
34
|
(send nil? #method_definition_macros
|
33
35
|
(sym $_)
|
@@ -70,7 +72,7 @@ module RuboCop
|
|
70
72
|
!method_name.match?(/^#{prefix}[^0-9]/) ||
|
71
73
|
method_name == expected_name(method_name, prefix) ||
|
72
74
|
method_name.end_with?('=') ||
|
73
|
-
|
75
|
+
allowed_method?(method_name)
|
74
76
|
end
|
75
77
|
|
76
78
|
def expected_name(method_name, prefix)
|
@@ -95,10 +97,6 @@ module RuboCop
|
|
95
97
|
cop_config['NamePrefix']
|
96
98
|
end
|
97
99
|
|
98
|
-
def allowed_methods
|
99
|
-
cop_config['AllowedMethods']
|
100
|
-
end
|
101
|
-
|
102
100
|
def method_definition_macros(macro_name)
|
103
101
|
cop_config['MethodDefinitionMacros'].include?(macro_name.to_s)
|
104
102
|
end
|
data/lib/rubocop/cop/offense.rb
CHANGED
@@ -54,14 +54,28 @@ module RuboCop
|
|
54
54
|
# @api private
|
55
55
|
attr_reader :status
|
56
56
|
|
57
|
+
# @api public
|
58
|
+
#
|
59
|
+
# @!attribute [r] corrector
|
60
|
+
#
|
61
|
+
# @return [Corrector | nil]
|
62
|
+
# the autocorrection for this offense, or `nil` when not available
|
63
|
+
attr_reader :corrector
|
64
|
+
|
65
|
+
PseudoSourceRange = Struct.new(:line, :column, :source_line, :begin_pos,
|
66
|
+
:end_pos)
|
67
|
+
|
68
|
+
NO_LOCATION = PseudoSourceRange.new(1, 0, '', 0, 1).freeze
|
69
|
+
|
57
70
|
# @api private
|
58
|
-
def initialize(severity, location, message, cop_name,
|
59
|
-
status = :uncorrected)
|
71
|
+
def initialize(severity, location, message, cop_name, # rubocop:disable Metrics/ParameterLists
|
72
|
+
status = :uncorrected, corrector = nil)
|
60
73
|
@severity = RuboCop::Cop::Severity.new(severity)
|
61
74
|
@location = location
|
62
75
|
@message = message.freeze
|
63
76
|
@cop_name = cop_name.freeze
|
64
77
|
@status = status
|
78
|
+
@corrector = corrector
|
65
79
|
freeze
|
66
80
|
end
|
67
81
|
|
data/lib/rubocop/cop/registry.rb
CHANGED
@@ -22,34 +22,42 @@ module RuboCop
|
|
22
22
|
|
23
23
|
# Registry that tracks all cops by their badge and department.
|
24
24
|
class Registry
|
25
|
+
include Enumerable
|
26
|
+
|
27
|
+
attr_reader :options
|
28
|
+
|
25
29
|
def initialize(cops = [], options = {})
|
26
30
|
@registry = {}
|
27
31
|
@departments = {}
|
28
32
|
@cops_by_cop_name = Hash.new { |hash, key| hash[key] = [] }
|
29
33
|
|
30
|
-
|
34
|
+
@enrollment_queue = cops
|
31
35
|
@options = options
|
32
36
|
end
|
33
37
|
|
34
38
|
def enlist(cop)
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
+
@enrollment_queue << cop
|
40
|
+
end
|
41
|
+
|
42
|
+
def dismiss(cop)
|
43
|
+
raise "Cop #{cop} could not be dismissed" unless @enrollment_queue.delete(cop)
|
39
44
|
end
|
40
45
|
|
41
46
|
# @return [Array<Symbol>] list of departments for current cops.
|
42
47
|
def departments
|
48
|
+
clear_enrollment_queue
|
43
49
|
@departments.keys
|
44
50
|
end
|
45
51
|
|
46
52
|
# @return [Registry] Cops for that specific department.
|
47
53
|
def with_department(department)
|
54
|
+
clear_enrollment_queue
|
48
55
|
with(@departments.fetch(department, []))
|
49
56
|
end
|
50
57
|
|
51
58
|
# @return [Registry] Cops not for a specific department.
|
52
59
|
def without_department(department)
|
60
|
+
clear_enrollment_queue
|
53
61
|
without_department = @departments.dup
|
54
62
|
without_department.delete(department)
|
55
63
|
|
@@ -119,6 +127,7 @@ module RuboCop
|
|
119
127
|
end
|
120
128
|
|
121
129
|
def unqualified_cop_names
|
130
|
+
clear_enrollment_queue
|
122
131
|
@unqualified_cop_names ||=
|
123
132
|
Set.new(@cops_by_cop_name.keys.map { |qn| File.basename(qn) }) <<
|
124
133
|
'RedundantCopDisableDirective'
|
@@ -126,18 +135,21 @@ module RuboCop
|
|
126
135
|
|
127
136
|
# @return [Hash{String => Array<Class>}]
|
128
137
|
def to_h
|
138
|
+
clear_enrollment_queue
|
129
139
|
@cops_by_cop_name
|
130
140
|
end
|
131
141
|
|
132
142
|
def cops
|
143
|
+
clear_enrollment_queue
|
133
144
|
@registry.values
|
134
145
|
end
|
135
146
|
|
136
147
|
def length
|
148
|
+
clear_enrollment_queue
|
137
149
|
@registry.size
|
138
150
|
end
|
139
151
|
|
140
|
-
def enabled(config, only, only_safe = false)
|
152
|
+
def enabled(config, only = [], only_safe = false)
|
141
153
|
select do |cop|
|
142
154
|
only.include?(cop.cop_name) || enabled?(cop, config, only_safe)
|
143
155
|
end
|
@@ -172,6 +184,7 @@ module RuboCop
|
|
172
184
|
end
|
173
185
|
|
174
186
|
def sort!
|
187
|
+
clear_enrollment_queue
|
175
188
|
@registry = Hash[@registry.sort_by { |badge, _| badge.cop_name }]
|
176
189
|
|
177
190
|
self
|
@@ -188,16 +201,57 @@ module RuboCop
|
|
188
201
|
# @param [String] cop_name
|
189
202
|
# @return [Class, nil]
|
190
203
|
def find_by_cop_name(cop_name)
|
191
|
-
|
204
|
+
to_h[cop_name].first
|
205
|
+
end
|
206
|
+
|
207
|
+
@global = new
|
208
|
+
|
209
|
+
class << self
|
210
|
+
attr_reader :global
|
211
|
+
end
|
212
|
+
|
213
|
+
def self.all
|
214
|
+
global.without_department(:Test).cops
|
215
|
+
end
|
216
|
+
|
217
|
+
def self.qualified_cop_name(name, origin)
|
218
|
+
global.qualified_cop_name(name, origin)
|
219
|
+
end
|
220
|
+
|
221
|
+
# Changes momentarily the global registry
|
222
|
+
# Intended for testing purposes
|
223
|
+
def self.with_temporary_global(temp_global = global.dup)
|
224
|
+
previous = @global
|
225
|
+
@global = temp_global
|
226
|
+
yield
|
227
|
+
ensure
|
228
|
+
@global = previous
|
192
229
|
end
|
193
230
|
|
194
231
|
private
|
195
232
|
|
233
|
+
def initialize_copy(reg)
|
234
|
+
initialize(reg.cops, reg.options)
|
235
|
+
end
|
236
|
+
|
237
|
+
def clear_enrollment_queue
|
238
|
+
return if @enrollment_queue.empty?
|
239
|
+
|
240
|
+
@enrollment_queue.each do |cop|
|
241
|
+
@registry[cop.badge] = cop
|
242
|
+
@departments[cop.department] ||= []
|
243
|
+
@departments[cop.department] << cop
|
244
|
+
@cops_by_cop_name[cop.cop_name] << cop
|
245
|
+
end
|
246
|
+
@enrollment_queue = []
|
247
|
+
end
|
248
|
+
|
196
249
|
def with(cops)
|
197
250
|
self.class.new(cops)
|
198
251
|
end
|
199
252
|
|
200
253
|
def qualify_badge(badge)
|
254
|
+
clear_enrollment_queue
|
201
255
|
@departments
|
202
256
|
.map { |department, _| badge.with_department(department) }
|
203
257
|
.select { |potential_badge| registered?(potential_badge) }
|
@@ -214,6 +268,7 @@ module RuboCop
|
|
214
268
|
end
|
215
269
|
|
216
270
|
def registered?(badge)
|
271
|
+
clear_enrollment_queue
|
217
272
|
@registry.key?(badge)
|
218
273
|
end
|
219
274
|
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for grouping of accessors in `class` and `module` bodies.
|
7
|
+
# By default it enforces accessors to be placed in grouped declarations,
|
8
|
+
# but it can be configured to enforce separating them in multiple declarations.
|
9
|
+
#
|
10
|
+
# @example EnforcedStyle: grouped (default)
|
11
|
+
# # bad
|
12
|
+
# class Foo
|
13
|
+
# attr_reader :bar
|
14
|
+
# attr_reader :baz
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# class Foo
|
19
|
+
# attr_reader :bar, :baz
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @example EnforcedStyle: separated
|
23
|
+
# # bad
|
24
|
+
# class Foo
|
25
|
+
# attr_reader :bar, :baz
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# class Foo
|
30
|
+
# attr_reader :bar
|
31
|
+
# attr_reader :baz
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
class AccessorGrouping < Cop
|
35
|
+
include ConfigurableEnforcedStyle
|
36
|
+
include VisibilityHelp
|
37
|
+
|
38
|
+
GROUPED_MSG = 'Group together all `%<accessor>s` attributes.'
|
39
|
+
SEPARATED_MSG = 'Use one attribute per `%<accessor>s`.'
|
40
|
+
|
41
|
+
ACCESSOR_METHODS = %i[attr_reader attr_writer attr_accessor attr].freeze
|
42
|
+
|
43
|
+
def on_class(node)
|
44
|
+
class_send_elements(node).each do |macro|
|
45
|
+
next unless accessor?(macro)
|
46
|
+
|
47
|
+
check(macro)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
alias on_sclass on_class
|
51
|
+
alias on_module on_class
|
52
|
+
|
53
|
+
def autocorrect(node)
|
54
|
+
lambda do |corrector|
|
55
|
+
corrector.replace(node, correction(node))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def previous_line_comment?(node)
|
62
|
+
comment_line?(processed_source[node.first_line - 2])
|
63
|
+
end
|
64
|
+
|
65
|
+
def class_send_elements(class_node)
|
66
|
+
class_def = class_node.body
|
67
|
+
|
68
|
+
if !class_def || class_def.def_type?
|
69
|
+
[]
|
70
|
+
elsif class_def.send_type?
|
71
|
+
[class_def]
|
72
|
+
else
|
73
|
+
class_def.each_child_node(:send).to_a
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def accessor?(send_node)
|
78
|
+
send_node.macro? && ACCESSOR_METHODS.include?(send_node.method_name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def check(send_node)
|
82
|
+
return if previous_line_comment?(send_node)
|
83
|
+
|
84
|
+
if grouped_style? && sibling_accessors(send_node).size > 1
|
85
|
+
add_offense(send_node)
|
86
|
+
elsif separated_style? && send_node.arguments.size > 1
|
87
|
+
add_offense(send_node)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def grouped_style?
|
92
|
+
style == :grouped
|
93
|
+
end
|
94
|
+
|
95
|
+
def separated_style?
|
96
|
+
style == :separated
|
97
|
+
end
|
98
|
+
|
99
|
+
def sibling_accessors(send_node)
|
100
|
+
send_node.parent.each_child_node(:send).select do |sibling|
|
101
|
+
accessor?(sibling) &&
|
102
|
+
sibling.method?(send_node.method_name) &&
|
103
|
+
node_visibility(sibling) == node_visibility(send_node) &&
|
104
|
+
!previous_line_comment?(sibling)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def message(send_node)
|
109
|
+
msg = grouped_style? ? GROUPED_MSG : SEPARATED_MSG
|
110
|
+
format(msg, accessor: send_node.method_name)
|
111
|
+
end
|
112
|
+
|
113
|
+
def correction(node)
|
114
|
+
if grouped_style?
|
115
|
+
accessors = sibling_accessors(node)
|
116
|
+
if node == accessors.first
|
117
|
+
group_accessors(node, accessors)
|
118
|
+
else
|
119
|
+
''
|
120
|
+
end
|
121
|
+
else
|
122
|
+
separate_accessors(node)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def group_accessors(node, accessors)
|
127
|
+
accessor_names = accessors.flat_map do |accessor|
|
128
|
+
accessor.arguments.map(&:source)
|
129
|
+
end
|
130
|
+
|
131
|
+
"#{node.method_name} #{accessor_names.join(', ')}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def separate_accessors(node)
|
135
|
+
node.arguments.map do |arg|
|
136
|
+
if arg == node.arguments.first
|
137
|
+
"#{node.method_name} #{arg.source}"
|
138
|
+
else
|
139
|
+
indent = ' ' * node.loc.column
|
140
|
+
"#{indent}#{node.method_name} #{arg.source}"
|
141
|
+
end
|
142
|
+
end.join("\n")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|