rubocop 1.45.1 → 1.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +3 -9
- data/lib/rubocop/comment_config.rb +17 -0
- data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +8 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -7
- data/lib/rubocop/cop/lint/debugger.rb +3 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -9
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +6 -10
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +7 -1
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +6 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -9
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +10 -7
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
- data/lib/rubocop/cop/style/accessor_grouping.rb +12 -11
- data/lib/rubocop/cop/style/array_intersect.rb +1 -1
- data/lib/rubocop/cop/style/documentation_method.rb +4 -4
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +5 -6
- data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +17 -5
- data/lib/rubocop/cop/team.rb +11 -8
- data/lib/rubocop/cop/util.rb +12 -3
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2c58d5ebb1a39e8a8f66fe34861ea52ae7c7d601c4f64e5f39c9b3f335a04b4
|
4
|
+
data.tar.gz: b0eab2e29b9875b27aa3eb069147ec82b3fc108fe15c81dcb43c68265b6757d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63da1401d75b3245df06193f264339cf62b180102c584b5b708ed1ba7191787bd71ae33636eb703406ab6ea87127854ba38c8348336f521113fee265d74da9cc
|
7
|
+
data.tar.gz: 7155f94dd7b68d2e103003bbfa95b74e2e4a9d9a8efd78c210adc227bc0a2b6cd399a7e7e285acd6934b070036ca0362d3b9560b9e92693bd9a9bc0497b71af6
|
data/README.md
CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
53
53
|
in your `Gemfile`:
|
54
54
|
|
55
55
|
```rb
|
56
|
-
gem 'rubocop', '~> 1.
|
56
|
+
gem 'rubocop', '~> 1.46', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -1630,13 +1630,12 @@ Lint/Debugger:
|
|
1630
1630
|
Description: 'Check for debugger calls.'
|
1631
1631
|
Enabled: true
|
1632
1632
|
VersionAdded: '0.14'
|
1633
|
-
VersionChanged: '1.
|
1633
|
+
VersionChanged: '1.46'
|
1634
1634
|
DebuggerMethods:
|
1635
1635
|
# Groups are available so that a specific group can be disabled in
|
1636
1636
|
# a user's configuration, but are otherwise not significant.
|
1637
1637
|
Kernel:
|
1638
1638
|
- binding.irb
|
1639
|
-
- p
|
1640
1639
|
- Kernel.binding.irb
|
1641
1640
|
Byebug:
|
1642
1641
|
- byebug
|
@@ -1646,9 +1645,6 @@ Lint/Debugger:
|
|
1646
1645
|
Capybara:
|
1647
1646
|
- save_and_open_page
|
1648
1647
|
- save_and_open_screenshot
|
1649
|
-
PP:
|
1650
|
-
- PP.pp
|
1651
|
-
- pp
|
1652
1648
|
debug.rb:
|
1653
1649
|
- binding.b
|
1654
1650
|
- binding.break
|
@@ -2927,6 +2923,7 @@ Naming/VariableNumber:
|
|
2927
2923
|
- rfc822 # Time#rfc822
|
2928
2924
|
- rfc2822 # Time#rfc2822
|
2929
2925
|
- rfc3339 # DateTime.rfc3339
|
2926
|
+
- x86_64 # Allowed by default as an underscore separated CPU architecture name
|
2930
2927
|
AllowedPatterns: []
|
2931
2928
|
|
2932
2929
|
#################### Security ##############################
|
@@ -3054,6 +3051,7 @@ Style/ArrayCoercion:
|
|
3054
3051
|
Style/ArrayIntersect:
|
3055
3052
|
Description: 'Use `array1.intersect?(array2)` instead of `(array1 & array2).any?`.'
|
3056
3053
|
Enabled: 'pending'
|
3054
|
+
Safe: false
|
3057
3055
|
VersionAdded: '1.40'
|
3058
3056
|
|
3059
3057
|
Style/ArrayJoin:
|
@@ -4027,10 +4025,6 @@ Style/InverseMethods:
|
|
4027
4025
|
:=~: :!~
|
4028
4026
|
:<: :>=
|
4029
4027
|
:>: :<=
|
4030
|
-
# `ActiveSupport` defines some common inverse methods. They are listed below,
|
4031
|
-
# and not enabled by default.
|
4032
|
-
# :present?: :blank?,
|
4033
|
-
# :include?: :exclude?
|
4034
4028
|
# `InverseBlocks` are methods that are inverted by inverting the return
|
4035
4029
|
# of the block that is passed to the method
|
4036
4030
|
InverseBlocks:
|
@@ -42,6 +42,10 @@ module RuboCop
|
|
42
42
|
disabled_line_ranges.none? { |range| range.include?(line_number) }
|
43
43
|
end
|
44
44
|
|
45
|
+
def cop_opted_in?(cop)
|
46
|
+
opt_in_cops.include?(cop.cop_name)
|
47
|
+
end
|
48
|
+
|
45
49
|
def cop_disabled_line_ranges
|
46
50
|
@cop_disabled_line_ranges ||= analyze
|
47
51
|
end
|
@@ -74,6 +78,19 @@ module RuboCop
|
|
74
78
|
extras
|
75
79
|
end
|
76
80
|
|
81
|
+
def opt_in_cops
|
82
|
+
@opt_in_cops ||= begin
|
83
|
+
cops = Set.new
|
84
|
+
each_directive do |directive|
|
85
|
+
next unless directive.enabled?
|
86
|
+
next if directive.all_cops?
|
87
|
+
|
88
|
+
cops.merge(directive.cop_names)
|
89
|
+
end
|
90
|
+
cops
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
77
94
|
def analyze # rubocop:todo Metrics/AbcSize
|
78
95
|
return {} if @no_directives
|
79
96
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Enforces the use of `processed_source.file_path` instead of `processed_source.buffer.name`.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# processed_source.buffer.name
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# processed_source.file_path
|
15
|
+
#
|
16
|
+
class ProcessedSourceBufferName < Base
|
17
|
+
extend AutoCorrector
|
18
|
+
|
19
|
+
MSG = 'Use `file_path` instead.'
|
20
|
+
|
21
|
+
RESTRICT_ON_SEND = %i[name].freeze
|
22
|
+
|
23
|
+
# @!method processed_source_buffer_name?(node)
|
24
|
+
def_node_matcher :processed_source_buffer_name?, <<~PATTERN
|
25
|
+
(send
|
26
|
+
(send
|
27
|
+
{(lvar :processed_source) (send nil? :processed_source)} :buffer) :name)
|
28
|
+
PATTERN
|
29
|
+
|
30
|
+
def on_send(node)
|
31
|
+
return unless processed_source_buffer_name?(node)
|
32
|
+
|
33
|
+
offense_range = node.children.first.loc.selector.begin.join(node.loc.expression.end)
|
34
|
+
|
35
|
+
add_offense(offense_range) do |corrector|
|
36
|
+
corrector.replace(offense_range, 'file_path')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -15,6 +15,7 @@ require_relative 'internal_affairs/node_matcher_directive'
|
|
15
15
|
require_relative 'internal_affairs/node_type_predicate'
|
16
16
|
require_relative 'internal_affairs/numblock_handler'
|
17
17
|
require_relative 'internal_affairs/offense_location_keyword'
|
18
|
+
require_relative 'internal_affairs/processed_source_buffer_name'
|
18
19
|
require_relative 'internal_affairs/redundant_context_config_parameter'
|
19
20
|
require_relative 'internal_affairs/redundant_described_class_as_subject'
|
20
21
|
require_relative 'internal_affairs/redundant_let_rubocop_config_new'
|
@@ -67,8 +67,7 @@ module RuboCop
|
|
67
67
|
|
68
68
|
outermost_send = outermost_send_on_same_line(heredoc_arg)
|
69
69
|
return unless outermost_send
|
70
|
-
return
|
71
|
-
return unless heredoc_arg.first_line != outermost_send.loc.end.line
|
70
|
+
return if end_keyword_before_closing_parentesis?(node)
|
72
71
|
return if subsequent_closing_parentheses_in_same_line?(outermost_send)
|
73
72
|
return if exist_argument_between_heredoc_end_and_closing_parentheses?(node)
|
74
73
|
|
@@ -160,6 +159,12 @@ module RuboCop
|
|
160
159
|
|
161
160
|
# Closing parenthesis helpers.
|
162
161
|
|
162
|
+
def end_keyword_before_closing_parentesis?(parenthesized_send_node)
|
163
|
+
parenthesized_send_node.ancestors.any? do |ancestor|
|
164
|
+
ancestor.loc.respond_to?(:end) && ancestor.loc.end&.source == 'end'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
163
168
|
def subsequent_closing_parentheses_in_same_line?(outermost_send)
|
164
169
|
last_arg_of_outer_send = outermost_send.last_argument
|
165
170
|
return false unless last_arg_of_outer_send&.loc.respond_to?(:end) &&
|
@@ -215,6 +220,7 @@ module RuboCop
|
|
215
220
|
end
|
216
221
|
|
217
222
|
def exist_argument_between_heredoc_end_and_closing_parentheses?(node)
|
223
|
+
return true unless node.loc.end
|
218
224
|
return false unless (heredoc_end = find_most_bottom_of_heredoc_end(node.arguments))
|
219
225
|
|
220
226
|
heredoc_end < node.loc.end.begin_pos &&
|
@@ -87,22 +87,26 @@ module RuboCop
|
|
87
87
|
corrector.replace(range, correction)
|
88
88
|
end
|
89
89
|
|
90
|
-
|
90
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
91
|
+
def ignored_literal_ranges(ast)
|
91
92
|
# which lines start inside a string literal?
|
92
93
|
return [] if ast.nil?
|
93
94
|
|
94
|
-
|
95
|
-
|
96
|
-
loc = str.location
|
95
|
+
ast.each_node(:str, :dstr, :array).with_object(Set.new) do |literal, ranges|
|
96
|
+
loc = literal.location
|
97
97
|
|
98
|
-
if
|
98
|
+
if literal.array_type?
|
99
|
+
next unless literal.percent_literal?
|
100
|
+
|
101
|
+
ranges << loc.expression
|
102
|
+
elsif literal.heredoc?
|
99
103
|
ranges << loc.heredoc_body
|
100
104
|
elsif loc.respond_to?(:begin) && loc.begin
|
101
105
|
ranges << loc.expression
|
102
106
|
end
|
103
107
|
end
|
104
|
-
ranges
|
105
108
|
end
|
109
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
106
110
|
|
107
111
|
def comment_ranges(comments)
|
108
112
|
comments.map(&:loc).map(&:expression)
|
@@ -119,7 +123,7 @@ module RuboCop
|
|
119
123
|
end
|
120
124
|
|
121
125
|
def ignored_ranges
|
122
|
-
@ignored_ranges ||=
|
126
|
+
@ignored_ranges ||= ignored_literal_ranges(processed_source.ast) +
|
123
127
|
comment_ranges(processed_source.comments)
|
124
128
|
end
|
125
129
|
|
@@ -70,6 +70,9 @@ module RuboCop
|
|
70
70
|
def on_send(node)
|
71
71
|
return unless debugger_method?(node)
|
72
72
|
|
73
|
+
# Basically, debugger methods are not used as a method argument without arguments.
|
74
|
+
return if node.arguments.empty? && node.each_ancestor(:send, :csend).any?
|
75
|
+
|
73
76
|
add_offense(node)
|
74
77
|
end
|
75
78
|
|
@@ -120,7 +120,7 @@ module RuboCop
|
|
120
120
|
|
121
121
|
def scoping_method_call?(child)
|
122
122
|
child.sclass_type? || eval_call?(child) || exec_call?(child) ||
|
123
|
-
class_constructor?
|
123
|
+
child.class_constructor? || allowed_method_name?(child)
|
124
124
|
end
|
125
125
|
|
126
126
|
def allowed_method_name?(node)
|
@@ -138,14 +138,6 @@ module RuboCop
|
|
138
138
|
def_node_matcher :exec_call?, <<~PATTERN
|
139
139
|
(block (send _ {:instance_exec :class_exec :module_exec} ...) ...)
|
140
140
|
PATTERN
|
141
|
-
|
142
|
-
# @!method class_constructor?(node)
|
143
|
-
def_node_matcher :class_constructor?, <<~PATTERN
|
144
|
-
({block numblock} {
|
145
|
-
(send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
|
146
|
-
(send (const {nil? cbase} :Data) :define ...)
|
147
|
-
} ...)
|
148
|
-
PATTERN
|
149
141
|
end
|
150
142
|
end
|
151
143
|
end
|
@@ -69,7 +69,7 @@ module RuboCop
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def on_in_pattern(node)
|
72
|
-
regexp_patterns =
|
72
|
+
regexp_patterns = regexp_patterns(node)
|
73
73
|
|
74
74
|
@valid_ref = regexp_patterns.map { |pattern| check_regexp(pattern) }.compact.max
|
75
75
|
end
|
@@ -90,16 +90,12 @@ module RuboCop
|
|
90
90
|
|
91
91
|
private
|
92
92
|
|
93
|
-
def
|
94
|
-
pattern =
|
95
|
-
|
96
|
-
case pattern.type
|
97
|
-
when :array_pattern, :match_alt
|
98
|
-
pattern.children
|
99
|
-
when :match_as
|
100
|
-
patterns(pattern)
|
101
|
-
else
|
93
|
+
def regexp_patterns(in_node)
|
94
|
+
pattern = in_node.pattern
|
95
|
+
if pattern.regexp_type?
|
102
96
|
[pattern]
|
97
|
+
else
|
98
|
+
pattern.each_descendant(:regexp).to_a
|
103
99
|
end
|
104
100
|
end
|
105
101
|
|
@@ -284,12 +284,18 @@ module RuboCop
|
|
284
284
|
.all? { |intervening| /\A\s*,\s*\Z/.match?(intervening) }
|
285
285
|
end
|
286
286
|
|
287
|
+
SIMILAR_COP_NAMES_CACHE = Hash.new do |hash, cop_name|
|
288
|
+
hash[:all_cop_names] = Registry.global.names unless hash.key?(:all_cop_names)
|
289
|
+
hash[cop_name] = NameSimilarity.find_similar_name(cop_name, hash[:all_cop_names])
|
290
|
+
end
|
291
|
+
private_constant :SIMILAR_COP_NAMES_CACHE
|
292
|
+
|
287
293
|
def describe(cop)
|
288
294
|
return 'all cops' if cop == 'all'
|
289
295
|
return "`#{remove_department_marker(cop)}` department" if department_marker?(cop)
|
290
296
|
return "`#{cop}`" if all_cop_names.include?(cop)
|
291
297
|
|
292
|
-
similar =
|
298
|
+
similar = SIMILAR_COP_NAMES_CACHE[cop]
|
293
299
|
similar ? "`#{cop}` (did you mean `#{similar}`?)" : "`#{cop}` (unknown cop)"
|
294
300
|
end
|
295
301
|
|
@@ -41,7 +41,8 @@ module RuboCop
|
|
41
41
|
|
42
42
|
def on_send(node)
|
43
43
|
return if node.receiver
|
44
|
-
return unless
|
44
|
+
return unless (parent = node.parent)
|
45
|
+
return unless parent.block_type? && parent.method?(:refine)
|
45
46
|
|
46
47
|
add_offense(node.loc.selector, message: format(MSG, current: node.method_name))
|
47
48
|
end
|
@@ -43,8 +43,12 @@ module RuboCop
|
|
43
43
|
return unless def_node
|
44
44
|
|
45
45
|
enum_conversion_call?(node) do |method_node, arguments|
|
46
|
-
|
47
|
-
|
46
|
+
next if method_node.call_type? &&
|
47
|
+
!method_node.method?(:__method__) && !method_node.method?(:__callee__)
|
48
|
+
next if method_name?(method_node, def_node.method_name) &&
|
49
|
+
arguments_match?(arguments, def_node)
|
50
|
+
|
51
|
+
add_offense(node)
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -167,14 +167,6 @@ module RuboCop
|
|
167
167
|
({block numblock} (send _ {:class_eval :instance_eval}) ...)
|
168
168
|
PATTERN
|
169
169
|
|
170
|
-
# @!method class_constructor?(node)
|
171
|
-
def_node_matcher :class_constructor?, <<~PATTERN
|
172
|
-
({block numblock} {
|
173
|
-
(send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
|
174
|
-
(send (const {nil? cbase} :Data) :define ...)
|
175
|
-
} ...)
|
176
|
-
PATTERN
|
177
|
-
|
178
170
|
def check_node(node)
|
179
171
|
return if node.nil?
|
180
172
|
|
@@ -273,7 +265,7 @@ module RuboCop
|
|
273
265
|
|
274
266
|
def eval_call?(child)
|
275
267
|
class_or_instance_eval?(child) ||
|
276
|
-
class_constructor?
|
268
|
+
child.class_constructor? ||
|
277
269
|
any_context_creating_methods?(child)
|
278
270
|
end
|
279
271
|
|
@@ -72,8 +72,9 @@ module RuboCop
|
|
72
72
|
def use_exception_variable_in_ensure?(resbody_node)
|
73
73
|
return false unless (exception_variable = resbody_node.exception_variable)
|
74
74
|
return false unless (ensure_node = resbody_node.each_ancestor(:ensure).first)
|
75
|
+
return false unless (ensure_body = ensure_node.body)
|
75
76
|
|
76
|
-
|
77
|
+
ensure_body.each_descendant(:lvar).map(&:source).include?(exception_variable.source)
|
77
78
|
end
|
78
79
|
|
79
80
|
def exception_objects(resbody_node)
|
@@ -95,19 +95,19 @@ module RuboCop
|
|
95
95
|
use_modifier_form_without_parenthesized_method_call?(method_dispatch_node)
|
96
96
|
end
|
97
97
|
|
98
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
98
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
99
99
|
def def_node_that_require_parentheses(node)
|
100
100
|
last_pair = node.parent.pairs.last
|
101
101
|
return unless last_pair.key.source == last_pair.value.source
|
102
102
|
return unless (dispatch_node = find_ancestor_method_dispatch_node(node))
|
103
|
-
return if
|
104
|
-
return
|
103
|
+
return if dispatch_node.parenthesized?
|
104
|
+
return if last_expression?(dispatch_node) && !method_dispatch_as_argument?(dispatch_node)
|
105
105
|
|
106
106
|
def_node = node.each_ancestor(:send, :csend, :super, :yield).first
|
107
107
|
|
108
108
|
DefNode.new(def_node) unless def_node && def_node.arguments.empty?
|
109
109
|
end
|
110
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
110
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
111
111
|
|
112
112
|
def find_ancestor_method_dispatch_node(node)
|
113
113
|
return unless (ancestor = node.parent.parent)
|
@@ -132,9 +132,12 @@ module RuboCop
|
|
132
132
|
ancestor.ancestors.any? { |node| node.respond_to?(:modifier_form?) && node.modifier_form? }
|
133
133
|
end
|
134
134
|
|
135
|
-
def last_expression?(
|
136
|
-
|
137
|
-
|
135
|
+
def last_expression?(node)
|
136
|
+
return false if node.right_sibling
|
137
|
+
return true unless (assignment_node = node.each_ancestor.find(&:assignment?))
|
138
|
+
return last_expression?(assignment_node.parent) if assignment_node.parent&.assignment?
|
139
|
+
|
140
|
+
!assignment_node.right_sibling
|
138
141
|
end
|
139
142
|
|
140
143
|
def method_dispatch_as_argument?(method_dispatch_node)
|
@@ -7,8 +7,8 @@ module RuboCop
|
|
7
7
|
# By default it enforces accessors to be placed in grouped declarations,
|
8
8
|
# but it can be configured to enforce separating them in multiple declarations.
|
9
9
|
#
|
10
|
-
# NOTE:
|
11
|
-
#
|
10
|
+
# NOTE: If there is a method call before the accessor method it is always allowed
|
11
|
+
# as it might be intended like Sorbet.
|
12
12
|
#
|
13
13
|
# @example EnforcedStyle: grouped (default)
|
14
14
|
# # bad
|
@@ -43,11 +43,9 @@ module RuboCop
|
|
43
43
|
GROUPED_MSG = 'Group together all `%<accessor>s` attributes.'
|
44
44
|
SEPARATED_MSG = 'Use one attribute per `%<accessor>s`.'
|
45
45
|
|
46
|
-
ACCESSOR_METHODS = %i[attr_reader attr_writer attr_accessor attr].freeze
|
47
|
-
|
48
46
|
def on_class(node)
|
49
47
|
class_send_elements(node).each do |macro|
|
50
|
-
next unless
|
48
|
+
next unless macro.attribute_accessor?
|
51
49
|
|
52
50
|
check(macro)
|
53
51
|
end
|
@@ -58,7 +56,7 @@ module RuboCop
|
|
58
56
|
private
|
59
57
|
|
60
58
|
def check(send_node)
|
61
|
-
return if previous_line_comment?(send_node)
|
59
|
+
return if previous_line_comment?(send_node) || !groupable_accessor?(send_node)
|
62
60
|
return unless (grouped_style? && sibling_accessors(send_node).size > 1) ||
|
63
61
|
(separated_style? && send_node.arguments.size > 1)
|
64
62
|
|
@@ -81,6 +79,13 @@ module RuboCop
|
|
81
79
|
comment_line?(processed_source[node.first_line - 2])
|
82
80
|
end
|
83
81
|
|
82
|
+
def groupable_accessor?(node)
|
83
|
+
return true unless (previous_expression = node.left_siblings.last)
|
84
|
+
return true unless previous_expression.send_type?
|
85
|
+
|
86
|
+
previous_expression.attribute_accessor? || previous_expression.access_modifier?
|
87
|
+
end
|
88
|
+
|
84
89
|
def class_send_elements(class_node)
|
85
90
|
class_def = class_node.body
|
86
91
|
|
@@ -93,10 +98,6 @@ module RuboCop
|
|
93
98
|
end
|
94
99
|
end
|
95
100
|
|
96
|
-
def accessor?(send_node)
|
97
|
-
send_node.macro? && ACCESSOR_METHODS.include?(send_node.method_name)
|
98
|
-
end
|
99
|
-
|
100
101
|
def grouped_style?
|
101
102
|
style == :grouped
|
102
103
|
end
|
@@ -107,7 +108,7 @@ module RuboCop
|
|
107
108
|
|
108
109
|
def sibling_accessors(send_node)
|
109
110
|
send_node.parent.each_child_node(:send).select do |sibling|
|
110
|
-
|
111
|
+
sibling.attribute_accessor? &&
|
111
112
|
sibling.method?(send_node.method_name) &&
|
112
113
|
node_visibility(sibling) == node_visibility(send_node) &&
|
113
114
|
!previous_line_comment?(sibling)
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
12
12
|
# `(array1 & array2).any?` and is more readable.
|
13
13
|
#
|
14
14
|
# @safety
|
15
|
-
# This cop cannot guarantee that array1 and array2 are
|
15
|
+
# This cop cannot guarantee that `array1` and `array2` are
|
16
16
|
# actually arrays while method `intersect?` is for arrays only.
|
17
17
|
#
|
18
18
|
# @example
|
@@ -101,16 +101,16 @@ module RuboCop
|
|
101
101
|
|
102
102
|
MSG = 'Missing method documentation comment.'
|
103
103
|
|
104
|
-
# @!method
|
105
|
-
def_node_matcher :
|
106
|
-
(send nil? :module_function ...)
|
104
|
+
# @!method modifier_node?(node)
|
105
|
+
def_node_matcher :modifier_node?, <<~PATTERN
|
106
|
+
(send nil? {:module_function :ruby2_keywords} ...)
|
107
107
|
PATTERN
|
108
108
|
|
109
109
|
def on_def(node)
|
110
110
|
return if node.method?(:initialize)
|
111
111
|
|
112
112
|
parent = node.parent
|
113
|
-
|
113
|
+
modifier_node?(parent) ? check(parent) : check(node)
|
114
114
|
end
|
115
115
|
alias on_defs on_def
|
116
116
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
|
75
75
|
non_redundant =
|
76
76
|
whitespace_in_free_space_mode?(node, class_elem) ||
|
77
|
-
backslash_b?(class_elem) ||
|
77
|
+
backslash_b?(class_elem) || octal_requiring_char_class?(class_elem) ||
|
78
78
|
requires_escape_outside_char_class?(class_elem)
|
79
79
|
|
80
80
|
!non_redundant
|
@@ -104,11 +104,10 @@ module RuboCop
|
|
104
104
|
elem == '\b'
|
105
105
|
end
|
106
106
|
|
107
|
-
def
|
108
|
-
#
|
109
|
-
#
|
110
|
-
|
111
|
-
elem == '\0'
|
107
|
+
def octal_requiring_char_class?(elem)
|
108
|
+
# The octal escapes \1 to \7 only work inside a character class
|
109
|
+
# because they would be a backreference outside it.
|
110
|
+
elem.match?(/\A\\[1-7]\z/)
|
112
111
|
end
|
113
112
|
|
114
113
|
def requires_escape_outside_char_class?(elem)
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
#
|
9
9
|
# @safety
|
10
10
|
# This cop is unsafe because `x..-1` and `x..` are only guaranteed to
|
11
|
-
# be equivalent for `Array#[]`, and the cop cannot determine what class
|
11
|
+
# be equivalent for `Array#[]`, `String#[]`, and the cop cannot determine what class
|
12
12
|
# the receiver is.
|
13
13
|
#
|
14
14
|
# For example:
|
@@ -82,10 +82,19 @@ module RuboCop
|
|
82
82
|
attr_accessor :largest_brackets
|
83
83
|
end
|
84
84
|
|
85
|
+
def on_new_investigation
|
86
|
+
super
|
87
|
+
|
88
|
+
# Prevent O(n2) checks (checking the entire matrix once for each child array) by caching
|
89
|
+
@matrix_of_complex_content_cache = Hash.new do |cache, node|
|
90
|
+
cache[node] = matrix_of_complex_content?(node)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
85
94
|
def on_array(node)
|
86
95
|
if bracketed_array_of?(:str, node)
|
87
96
|
return if complex_content?(node.values)
|
88
|
-
return if
|
97
|
+
return if within_matrix_of_complex_content?(node)
|
89
98
|
|
90
99
|
check_bracketed_array(node, 'w')
|
91
100
|
elsif node.percent_literal?(:string)
|
@@ -95,12 +104,15 @@ module RuboCop
|
|
95
104
|
|
96
105
|
private
|
97
106
|
|
98
|
-
def
|
107
|
+
def within_matrix_of_complex_content?(node)
|
99
108
|
return false unless (parent = node.parent)
|
100
109
|
|
101
|
-
parent.array_type? &&
|
102
|
-
|
103
|
-
|
110
|
+
parent.array_type? && @matrix_of_complex_content_cache[parent]
|
111
|
+
end
|
112
|
+
|
113
|
+
def matrix_of_complex_content?(array)
|
114
|
+
array.values.all?(&:array_type?) &&
|
115
|
+
array.values.any? { |subarray| complex_content?(subarray.values) }
|
104
116
|
end
|
105
117
|
|
106
118
|
def complex_content?(strings, complex_regex: word_regex)
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -28,7 +28,7 @@ module RuboCop
|
|
28
28
|
def self.mobilize_cops(cop_classes, config, options = {})
|
29
29
|
cop_classes = Registry.new(cop_classes.to_a, options) unless cop_classes.is_a?(Registry)
|
30
30
|
|
31
|
-
cop_classes.
|
31
|
+
cop_classes.map do |cop_class|
|
32
32
|
cop_class.new(config, options)
|
33
33
|
end
|
34
34
|
end
|
@@ -58,6 +58,7 @@ module RuboCop
|
|
58
58
|
@options = options
|
59
59
|
reset
|
60
60
|
@ready = true
|
61
|
+
@registry = Registry.new(cops, options.dup)
|
61
62
|
|
62
63
|
validate_config
|
63
64
|
end
|
@@ -84,7 +85,7 @@ module RuboCop
|
|
84
85
|
# until there are no corrections left to perform
|
85
86
|
# To speed things up, run autocorrecting cops by themselves, and only
|
86
87
|
# run the other cops when no corrections are left
|
87
|
-
on_duty = roundup_relevant_cops(processed_source
|
88
|
+
on_duty = roundup_relevant_cops(processed_source)
|
88
89
|
|
89
90
|
autocorrect_cops, other_cops = on_duty.partition(&:autocorrect?)
|
90
91
|
report = investigate_partial(autocorrect_cops, processed_source,
|
@@ -130,7 +131,7 @@ module RuboCop
|
|
130
131
|
# holds source read in from stdin, when --stdin option is used
|
131
132
|
@options[:stdin] = new_source
|
132
133
|
else
|
133
|
-
filename = processed_source.
|
134
|
+
filename = processed_source.file_path
|
134
135
|
File.write(filename, new_source)
|
135
136
|
end
|
136
137
|
@updated_source_file = true
|
@@ -156,11 +157,13 @@ module RuboCop
|
|
156
157
|
end
|
157
158
|
|
158
159
|
# @return [Array<cop>]
|
159
|
-
def roundup_relevant_cops(
|
160
|
-
cops.
|
161
|
-
|
162
|
-
|
163
|
-
|
160
|
+
def roundup_relevant_cops(processed_source)
|
161
|
+
cops.select do |cop|
|
162
|
+
next true if processed_source.comment_config.cop_opted_in?(cop)
|
163
|
+
next false unless @registry.enabled?(cop, @config)
|
164
|
+
next false if cop.excluded_file?(processed_source.file_path)
|
165
|
+
|
166
|
+
support_target_ruby_version?(cop) && support_target_rails_version?(cop)
|
164
167
|
end
|
165
168
|
end
|
166
169
|
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
# This module contains a collection of useful utility methods.
|
6
|
+
# rubocop:disable Metrics/ModuleLength
|
6
7
|
module Util
|
7
8
|
include PathUtil
|
8
9
|
|
@@ -92,13 +93,20 @@ module RuboCop
|
|
92
93
|
sexp.each_child_node { |elem| on_node(syms, elem, excludes, &block) }
|
93
94
|
end
|
94
95
|
|
96
|
+
# Arbitrarily chosen value, should be enough to cover
|
97
|
+
# the most nested source code in real world projects.
|
98
|
+
MAX_LINE_BEGINS_REGEX_INDEX = 50
|
95
99
|
LINE_BEGINS_REGEX_CACHE = Hash.new do |hash, index|
|
96
|
-
hash[index] = /^\s{#{index}}\S/
|
100
|
+
hash[index] = /^\s{#{index}}\S/ if index <= MAX_LINE_BEGINS_REGEX_INDEX
|
97
101
|
end
|
98
|
-
private_constant :LINE_BEGINS_REGEX_CACHE
|
102
|
+
private_constant :MAX_LINE_BEGINS_REGEX_INDEX, :LINE_BEGINS_REGEX_CACHE
|
99
103
|
|
100
104
|
def begins_its_line?(range)
|
101
|
-
|
105
|
+
if (regex = LINE_BEGINS_REGEX_CACHE[range.column])
|
106
|
+
range.source_line.match?(regex)
|
107
|
+
else
|
108
|
+
range.source_line.index(/\S/) == range.column
|
109
|
+
end
|
102
110
|
end
|
103
111
|
|
104
112
|
# Returns, for example, a bare `if` node if the given node is an `if`
|
@@ -190,5 +198,6 @@ module RuboCop
|
|
190
198
|
source == target || (source.is_a?(Array) && source.include?(target))
|
191
199
|
end
|
192
200
|
end
|
201
|
+
# rubocop:enable Metrics/ModuleLength
|
193
202
|
end
|
194
203
|
end
|
@@ -69,7 +69,7 @@ module CopHelper
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def _investigate(cop, processed_source)
|
72
|
-
team = RuboCop::Cop::Team.new([cop],
|
72
|
+
team = RuboCop::Cop::Team.new([cop], configuration, raise_error: true)
|
73
73
|
report = team.investigate(processed_source)
|
74
74
|
@last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
|
75
75
|
report.offenses.reject(&:disabled?)
|
data/lib/rubocop/target_ruby.rb
CHANGED
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
# The kind of Ruby that code inspected by RuboCop is written in.
|
5
5
|
# @api private
|
6
6
|
class TargetRuby
|
7
|
-
KNOWN_RUBIES = [2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2].freeze
|
7
|
+
KNOWN_RUBIES = [2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3].freeze
|
8
8
|
DEFAULT_VERSION = 2.6
|
9
9
|
|
10
10
|
OBSOLETE_RUBIES = {
|
data/lib/rubocop/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.46.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-02-
|
13
|
+
date: 2023-02-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -120,7 +120,7 @@ dependencies:
|
|
120
120
|
requirements:
|
121
121
|
- - ">="
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version: 1.
|
123
|
+
version: 1.26.0
|
124
124
|
- - "<"
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: '2.0'
|
@@ -130,7 +130,7 @@ dependencies:
|
|
130
130
|
requirements:
|
131
131
|
- - ">="
|
132
132
|
- !ruby/object:Gem::Version
|
133
|
-
version: 1.
|
133
|
+
version: 1.26.0
|
134
134
|
- - "<"
|
135
135
|
- !ruby/object:Gem::Version
|
136
136
|
version: '2.0'
|
@@ -281,6 +281,7 @@ files:
|
|
281
281
|
- lib/rubocop/cop/internal_affairs/node_type_predicate.rb
|
282
282
|
- lib/rubocop/cop/internal_affairs/numblock_handler.rb
|
283
283
|
- lib/rubocop/cop/internal_affairs/offense_location_keyword.rb
|
284
|
+
- lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb
|
284
285
|
- lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb
|
285
286
|
- lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb
|
286
287
|
- lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb
|
@@ -980,7 +981,7 @@ metadata:
|
|
980
981
|
homepage_uri: https://rubocop.org/
|
981
982
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
982
983
|
source_code_uri: https://github.com/rubocop/rubocop/
|
983
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
984
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.46/
|
984
985
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
985
986
|
rubygems_mfa_required: 'true'
|
986
987
|
post_install_message:
|