rubocop 0.67.2 → 0.68.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +86 -233
  4. data/exe/rubocop +0 -12
  5. data/lib/rubocop.rb +13 -30
  6. data/lib/rubocop/ast/builder.rb +4 -0
  7. data/lib/rubocop/ast/node/alias_node.rb +24 -0
  8. data/lib/rubocop/ast/node/class_node.rb +31 -0
  9. data/lib/rubocop/ast/node/module_node.rb +24 -0
  10. data/lib/rubocop/ast/node/range_node.rb +7 -0
  11. data/lib/rubocop/ast/node/resbody_node.rb +12 -0
  12. data/lib/rubocop/ast/node/self_class_node.rb +24 -0
  13. data/lib/rubocop/cli.rb +40 -4
  14. data/lib/rubocop/config.rb +9 -7
  15. data/lib/rubocop/config_loader.rb +48 -7
  16. data/lib/rubocop/config_loader_resolver.rb +5 -4
  17. data/lib/rubocop/cop/commissioner.rb +24 -0
  18. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +18 -6
  19. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +12 -14
  20. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +9 -20
  21. data/lib/rubocop/cop/layout/align_arguments.rb +93 -0
  22. data/lib/rubocop/cop/layout/align_parameters.rb +57 -33
  23. data/lib/rubocop/cop/layout/class_structure.rb +5 -5
  24. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +6 -8
  25. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +3 -6
  26. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +1 -2
  27. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -0
  28. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +292 -0
  29. data/lib/rubocop/cop/layout/{first_parameter_indentation.rb → indent_first_argument.rb} +11 -12
  30. data/lib/rubocop/cop/layout/{indent_array.rb → indent_first_array_element.rb} +2 -2
  31. data/lib/rubocop/cop/layout/{indent_hash.rb → indent_first_hash_element.rb} +2 -2
  32. data/lib/rubocop/cop/layout/indent_first_parameter.rb +96 -0
  33. data/lib/rubocop/cop/layout/indentation_width.rb +4 -16
  34. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -4
  35. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -16
  36. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -2
  37. data/lib/rubocop/cop/lint/duplicate_methods.rb +6 -8
  38. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -8
  39. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +157 -0
  40. data/lib/rubocop/cop/lint/inherit_exception.rb +3 -4
  41. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +18 -1
  42. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -5
  43. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +25 -5
  44. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -6
  45. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -2
  46. data/lib/rubocop/cop/message_annotator.rb +1 -0
  47. data/lib/rubocop/cop/metrics/line_length.rb +139 -28
  48. data/lib/rubocop/cop/metrics/perceived_complexity.rb +3 -4
  49. data/lib/rubocop/cop/mixin/check_line_breakable.rb +190 -0
  50. data/lib/rubocop/cop/mixin/{array_hash_indentation.rb → multiline_element_indentation.rb} +3 -2
  51. data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -7
  52. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +33 -4
  53. data/lib/rubocop/cop/rails/active_record_override.rb +23 -8
  54. data/lib/rubocop/cop/rails/delegate.rb +5 -8
  55. data/lib/rubocop/cop/rails/environment_comparison.rb +5 -3
  56. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  57. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +3 -3
  58. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  59. data/lib/rubocop/cop/rails/skips_model_validations.rb +6 -7
  60. data/lib/rubocop/cop/rails/time_zone.rb +3 -10
  61. data/lib/rubocop/cop/rails/validation.rb +3 -0
  62. data/lib/rubocop/cop/registry.rb +3 -3
  63. data/lib/rubocop/cop/style/alias.rb +13 -7
  64. data/lib/rubocop/cop/style/block_delimiters.rb +20 -0
  65. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -21
  66. data/lib/rubocop/cop/style/class_methods.rb +16 -24
  67. data/lib/rubocop/cop/style/conditional_assignment.rb +20 -49
  68. data/lib/rubocop/cop/style/documentation.rb +3 -7
  69. data/lib/rubocop/cop/style/format_string.rb +18 -21
  70. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  71. data/lib/rubocop/cop/style/inverse_methods.rb +4 -0
  72. data/lib/rubocop/cop/style/lambda.rb +12 -8
  73. data/lib/rubocop/cop/style/mixin_grouping.rb +8 -10
  74. data/lib/rubocop/cop/style/module_function.rb +2 -3
  75. data/lib/rubocop/cop/style/next.rb +10 -14
  76. data/lib/rubocop/cop/style/one_line_conditional.rb +5 -3
  77. data/lib/rubocop/cop/style/optional_arguments.rb +1 -4
  78. data/lib/rubocop/cop/style/random_with_offset.rb +44 -47
  79. data/lib/rubocop/cop/style/redundant_return.rb +6 -14
  80. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  81. data/lib/rubocop/cop/style/safe_navigation.rb +3 -0
  82. data/lib/rubocop/cop/style/struct_inheritance.rb +2 -3
  83. data/lib/rubocop/cop/style/symbol_proc.rb +20 -40
  84. data/lib/rubocop/cop/style/unless_else.rb +1 -2
  85. data/lib/rubocop/cop/style/yoda_condition.rb +8 -7
  86. data/lib/rubocop/cop/util.rb +2 -4
  87. data/lib/rubocop/file_finder.rb +5 -10
  88. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -0
  89. data/lib/rubocop/node_pattern.rb +304 -170
  90. data/lib/rubocop/options.rb +4 -1
  91. data/lib/rubocop/rspec/shared_contexts.rb +3 -0
  92. data/lib/rubocop/version.rb +1 -1
  93. data/lib/rubocop/yaml_duplication_checker.rb +1 -1
  94. metadata +26 -50
  95. data/lib/rubocop/cop/performance/caller.rb +0 -69
  96. data/lib/rubocop/cop/performance/case_when_splat.rb +0 -177
  97. data/lib/rubocop/cop/performance/casecmp.rb +0 -108
  98. data/lib/rubocop/cop/performance/chain_array_allocation.rb +0 -78
  99. data/lib/rubocop/cop/performance/compare_with_block.rb +0 -122
  100. data/lib/rubocop/cop/performance/count.rb +0 -102
  101. data/lib/rubocop/cop/performance/detect.rb +0 -110
  102. data/lib/rubocop/cop/performance/double_start_end_with.rb +0 -94
  103. data/lib/rubocop/cop/performance/end_with.rb +0 -56
  104. data/lib/rubocop/cop/performance/fixed_size.rb +0 -97
  105. data/lib/rubocop/cop/performance/flat_map.rb +0 -78
  106. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +0 -99
  107. data/lib/rubocop/cop/performance/open_struct.rb +0 -46
  108. data/lib/rubocop/cop/performance/range_include.rb +0 -50
  109. data/lib/rubocop/cop/performance/redundant_block_call.rb +0 -93
  110. data/lib/rubocop/cop/performance/redundant_match.rb +0 -56
  111. data/lib/rubocop/cop/performance/redundant_merge.rb +0 -183
  112. data/lib/rubocop/cop/performance/regexp_match.rb +0 -265
  113. data/lib/rubocop/cop/performance/reverse_each.rb +0 -42
  114. data/lib/rubocop/cop/performance/size.rb +0 -77
  115. data/lib/rubocop/cop/performance/start_with.rb +0 -59
  116. data/lib/rubocop/cop/performance/string_replacement.rb +0 -173
  117. data/lib/rubocop/cop/performance/times_map.rb +0 -71
  118. data/lib/rubocop/cop/performance/unfreeze_string.rb +0 -50
  119. data/lib/rubocop/cop/performance/uri_default_parser.rb +0 -47
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # This cop checks for double `#start_with?` or `#end_with?` calls
7
- # separated by `||`. In some cases such calls can be replaced
8
- # with an single `#start_with?`/`#end_with?` call.
9
- #
10
- # @example
11
- # # bad
12
- # str.start_with?("a") || str.start_with?(Some::CONST)
13
- # str.start_with?("a", "b") || str.start_with?("c")
14
- # str.end_with?(var1) || str.end_with?(var2)
15
- #
16
- # # good
17
- # str.start_with?("a", Some::CONST)
18
- # str.start_with?("a", "b", "c")
19
- # str.end_with?(var1, var2)
20
- class DoubleStartEndWith < Cop
21
- MSG = 'Use `%<receiver>s.%<method>s(%<combined_args>s)` ' \
22
- 'instead of `%<original_code>s`.'.freeze
23
-
24
- def on_or(node)
25
- receiver,
26
- method,
27
- first_call_args,
28
- second_call_args = process_source(node)
29
-
30
- return unless receiver && second_call_args.all?(&:pure?)
31
-
32
- combined_args = combine_args(first_call_args, second_call_args)
33
-
34
- add_offense_for_double_call(node, receiver, method, combined_args)
35
- end
36
-
37
- def autocorrect(node)
38
- _receiver, _method,
39
- first_call_args, second_call_args = process_source(node)
40
-
41
- combined_args = combine_args(first_call_args, second_call_args)
42
- first_argument = first_call_args.first.loc.expression
43
- last_argument = second_call_args.last.loc.expression
44
- range = first_argument.join(last_argument)
45
-
46
- lambda do |corrector|
47
- corrector.replace(range, combined_args)
48
- end
49
- end
50
-
51
- private
52
-
53
- def process_source(node)
54
- if check_for_active_support_aliases?
55
- check_with_active_support_aliases(node)
56
- else
57
- two_start_end_with_calls(node)
58
- end
59
- end
60
-
61
- def combine_args(first_call_args, second_call_args)
62
- (first_call_args + second_call_args).map(&:source).join(', ')
63
- end
64
-
65
- def add_offense_for_double_call(node, receiver, method, combined_args)
66
- msg = format(MSG, receiver: receiver.source,
67
- method: method,
68
- combined_args: combined_args,
69
- original_code: node.source)
70
-
71
- add_offense(node, message: msg)
72
- end
73
-
74
- def check_for_active_support_aliases?
75
- cop_config['IncludeActiveSupportAliases']
76
- end
77
-
78
- def_node_matcher :two_start_end_with_calls, <<-PATTERN
79
- (or
80
- (send $_recv [{:start_with? :end_with?} $_method] $...)
81
- (send _recv _method $...))
82
- PATTERN
83
-
84
- def_node_matcher :check_with_active_support_aliases, <<-PATTERN
85
- (or
86
- (send $_recv
87
- [{:start_with? :starts_with? :end_with? :ends_with?} $_method]
88
- $...)
89
- (send _recv _method $...))
90
- PATTERN
91
- end
92
- end
93
- end
94
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # This cop identifies unnecessary use of a regex where `String#end_with?`
7
- # would suffice.
8
- #
9
- # @example
10
- # # bad
11
- # 'abc'.match?(/bc\Z/)
12
- # 'abc' =~ /bc\Z/
13
- # 'abc'.match(/bc\Z/)
14
- #
15
- # # good
16
- # 'abc'.end_with?('bc')
17
- class EndWith < Cop
18
- MSG = 'Use `String#end_with?` instead of a regex match anchored to ' \
19
- 'the end of the string.'.freeze
20
- SINGLE_QUOTE = "'".freeze
21
-
22
- def_node_matcher :redundant_regex?, <<-PATTERN
23
- {(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_end?) (regopt)))
24
- (send (regexp (str $#literal_at_end?) (regopt)) {:match :=~} $_)}
25
- PATTERN
26
-
27
- def literal_at_end?(regex_str)
28
- # is this regexp 'literal' in the sense of only matching literal
29
- # chars, rather than using metachars like . and * and so on?
30
- # also, is it anchored at the end of the string?
31
- regex_str =~ /\A(?:#{LITERAL_REGEX})+\\z\z/
32
- end
33
-
34
- def on_send(node)
35
- return unless redundant_regex?(node)
36
-
37
- add_offense(node)
38
- end
39
-
40
- def autocorrect(node)
41
- redundant_regex?(node) do |receiver, regex_str|
42
- receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
43
- regex_str = regex_str[0..-3] # drop \Z anchor
44
- regex_str = interpret_string_escapes(regex_str)
45
-
46
- lambda do |corrector|
47
- new_source = receiver.source + '.end_with?(' +
48
- to_string_literal(regex_str) + ')'
49
- corrector.replace(node.source_range, new_source)
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # Do not compute the size of statically sized objects.
7
- #
8
- # @example
9
- # # String methods
10
- # # bad
11
- # 'foo'.size
12
- # %q[bar].count
13
- # %(qux).length
14
- #
15
- # # Symbol methods
16
- # # bad
17
- # :fred.size
18
- # :'baz'.length
19
- #
20
- # # Array methods
21
- # # bad
22
- # [1, 2, thud].count
23
- # %W(1, 2, bar).size
24
- #
25
- # # Hash methods
26
- # # bad
27
- # { a: corge, b: grault }.length
28
- #
29
- # # good
30
- # foo.size
31
- # bar.count
32
- # qux.length
33
- #
34
- # # good
35
- # :"#{fred}".size
36
- # CONST = :baz.length
37
- #
38
- # # good
39
- # [1, 2, *thud].count
40
- # garply = [1, 2, 3]
41
- # garly.size
42
- #
43
- # # good
44
- # { a: corge, **grault }.length
45
- # waldo = { a: corge, b: grault }
46
- # waldo.size
47
- #
48
- class FixedSize < Cop
49
- MSG = 'Do not compute the size of statically sized objects.'.freeze
50
-
51
- def_node_matcher :counter, <<-MATCHER
52
- (send ${array hash str sym} {:count :length :size} $...)
53
- MATCHER
54
-
55
- def on_send(node)
56
- return if allowed_parent?(node.parent)
57
-
58
- counter(node) do |var, arg|
59
- return if allowed_variable?(var) || allowed_argument?(arg)
60
-
61
- add_offense(node)
62
- end
63
- end
64
-
65
- private
66
-
67
- def allowed_variable?(var)
68
- contains_splat?(var) || contains_double_splat?(var)
69
- end
70
-
71
- def allowed_argument?(arg)
72
- arg && non_string_argument?(arg.first)
73
- end
74
-
75
- def allowed_parent?(node)
76
- node && (node.casgn_type? || node.block_type?)
77
- end
78
-
79
- def contains_splat?(node)
80
- return unless node.array_type?
81
-
82
- node.each_child_node(:splat).any?
83
- end
84
-
85
- def contains_double_splat?(node)
86
- return unless node.hash_type?
87
-
88
- node.each_child_node(:kwsplat).any?
89
- end
90
-
91
- def non_string_argument?(node)
92
- node && !node.str_type?
93
- end
94
- end
95
- end
96
- end
97
- end
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # This cop is used to identify usages of
7
- #
8
- # @example
9
- # # bad
10
- # [1, 2, 3, 4].map { |e| [e, e] }.flatten(1)
11
- # [1, 2, 3, 4].collect { |e| [e, e] }.flatten(1)
12
- #
13
- # # good
14
- # [1, 2, 3, 4].flat_map { |e| [e, e] }
15
- # [1, 2, 3, 4].map { |e| [e, e] }.flatten
16
- # [1, 2, 3, 4].collect { |e| [e, e] }.flatten
17
- class FlatMap < Cop
18
- include RangeHelp
19
-
20
- MSG = 'Use `flat_map` instead of `%<method>s...%<flatten>s`.'.freeze
21
- FLATTEN_MULTIPLE_LEVELS = ' Beware, `flat_map` only flattens 1 level ' \
22
- 'and `flatten` can be used to flatten ' \
23
- 'multiple levels.'.freeze
24
-
25
- def_node_matcher :flat_map_candidate?, <<-PATTERN
26
- (send (block $(send _ ${:collect :map}) ...) ${:flatten :flatten!} $...)
27
- PATTERN
28
-
29
- def on_send(node)
30
- flat_map_candidate?(node) do |map_node, first_method, flatten, params|
31
- flatten_level, = *params.first
32
- if cop_config['EnabledForFlattenWithoutParams'] && !flatten_level
33
- offense_for_levels(node, map_node, first_method, flatten)
34
- elsif flatten_level == 1
35
- offense_for_method(node, map_node, first_method, flatten)
36
- end
37
- end
38
- end
39
-
40
- def autocorrect(node)
41
- map_node, _first_method, _flatten, params = flat_map_candidate?(node)
42
- flatten_level, = *params.first
43
-
44
- return unless flatten_level
45
-
46
- range = range_between(node.loc.dot.begin_pos,
47
- node.source_range.end_pos)
48
-
49
- lambda do |corrector|
50
- corrector.remove(range)
51
- corrector.replace(map_node.loc.selector, 'flat_map')
52
- end
53
- end
54
-
55
- private
56
-
57
- def offense_for_levels(node, map_node, first_method, flatten)
58
- message = MSG + FLATTEN_MULTIPLE_LEVELS
59
- register_offense(node, map_node, first_method, flatten, message)
60
- end
61
-
62
- def offense_for_method(node, map_node, first_method, flatten)
63
- register_offense(node, map_node, first_method, flatten, MSG)
64
- end
65
-
66
- def register_offense(node, map_node, first_method, flatten, message)
67
- range = range_between(map_node.loc.selector.begin_pos,
68
- node.loc.expression.end_pos)
69
-
70
- add_offense(node,
71
- location: range,
72
- message: format(message, method: first_method,
73
- flatten: flatten))
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # This cop checks for inefficient searching of keys and values within
7
- # hashes.
8
- #
9
- # `Hash#keys.include?` is less efficient than `Hash#key?` because
10
- # the former allocates a new array and then performs an O(n) search
11
- # through that array, while `Hash#key?` does not allocate any array and
12
- # performs a faster O(1) search for the key.
13
- #
14
- # `Hash#values.include?` is less efficient than `Hash#value?`. While they
15
- # both perform an O(n) search through all of the values, calling `values`
16
- # allocates a new array while using `value?` does not.
17
- #
18
- # @example
19
- # # bad
20
- # { a: 1, b: 2 }.keys.include?(:a)
21
- # { a: 1, b: 2 }.keys.include?(:z)
22
- # h = { a: 1, b: 2 }; h.keys.include?(100)
23
- #
24
- # # good
25
- # { a: 1, b: 2 }.key?(:a)
26
- # { a: 1, b: 2 }.has_key?(:z)
27
- # h = { a: 1, b: 2 }; h.key?(100)
28
- #
29
- # # bad
30
- # { a: 1, b: 2 }.values.include?(2)
31
- # { a: 1, b: 2 }.values.include?('garbage')
32
- # h = { a: 1, b: 2 }; h.values.include?(nil)
33
- #
34
- # # good
35
- # { a: 1, b: 2 }.value?(2)
36
- # { a: 1, b: 2 }.has_value?('garbage')
37
- # h = { a: 1, b: 2 }; h.value?(nil)
38
- #
39
- class InefficientHashSearch < Cop
40
- def_node_matcher :inefficient_include?, <<-PATTERN
41
- (send (send $_ {:keys :values}) :include? _)
42
- PATTERN
43
-
44
- def on_send(node)
45
- inefficient_include?(node) do |receiver|
46
- return if receiver.nil?
47
-
48
- add_offense(node)
49
- end
50
- end
51
-
52
- def autocorrect(node)
53
- lambda do |corrector|
54
- # Replace `keys.include?` or `values.include?` with the appropriate
55
- # `key?`/`value?` method.
56
- corrector.replace(
57
- node.loc.expression,
58
- "#{autocorrect_hash_expression(node)}."\
59
- "#{autocorrect_method(node)}(#{autocorrect_argument(node)})"
60
- )
61
- end
62
- end
63
-
64
- private
65
-
66
- def message(node)
67
- "Use `##{autocorrect_method(node)}` instead of "\
68
- "`##{current_method(node)}.include?`."
69
- end
70
-
71
- def autocorrect_method(node)
72
- case current_method(node)
73
- when :keys then use_long_method ? 'has_key?' : 'key?'
74
- when :values then use_long_method ? 'has_value?' : 'value?'
75
- end
76
- end
77
-
78
- def current_method(node)
79
- node.receiver.method_name
80
- end
81
-
82
- def use_long_method
83
- preferred_config = config.for_all_cops['Style/PreferredHashMethods']
84
- preferred_config &&
85
- preferred_config['EnforcedStyle'] == 'long' &&
86
- preferred_config['Enabled']
87
- end
88
-
89
- def autocorrect_argument(node)
90
- node.arguments.first.source
91
- end
92
-
93
- def autocorrect_hash_expression(node)
94
- node.receiver.receiver.source
95
- end
96
- end
97
- end
98
- end
99
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # This cop checks for `OpenStruct.new` calls.
7
- # Instantiation of an `OpenStruct` invalidates
8
- # Ruby global method cache as it causes dynamic method
9
- # definition during program runtime.
10
- # This could have an effect on performance,
11
- # especially in case of single-threaded
12
- # applications with multiple `OpenStruct` instantiations.
13
- #
14
- # @example
15
- # # bad
16
- # class MyClass
17
- # def my_method
18
- # OpenStruct.new(my_key1: 'my_value1', my_key2: 'my_value2')
19
- # end
20
- # end
21
- #
22
- # # good
23
- # class MyClass
24
- # MyStruct = Struct.new(:my_key1, :my_key2)
25
- # def my_method
26
- # MyStruct.new('my_value1', 'my_value2')
27
- # end
28
- # end
29
- #
30
- class OpenStruct < Cop
31
- MSG = 'Consider using `Struct` over `OpenStruct` ' \
32
- 'to optimize the performance.'.freeze
33
-
34
- def_node_matcher :open_struct, <<-PATTERN
35
- (send (const {nil? cbase} :OpenStruct) :new ...)
36
- PATTERN
37
-
38
- def on_send(node)
39
- open_struct(node) do |method|
40
- add_offense(node, location: :selector, message: format(MSG, method))
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end