rubocop 1.16.1 → 1.17.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/lib/rubocop/cop/layout/dot_position.rb +7 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +13 -15
- data/lib/rubocop/cop/layout/hash_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +8 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +11 -9
- data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +6 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +13 -1
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +32 -17
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +93 -65
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -0
- data/lib/rubocop/cop/migration/department_name.rb +3 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +29 -0
- data/lib/rubocop/cop/style/raise_args.rb +2 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +9 -1
- data/lib/rubocop/directive_comment.rb +53 -5
- data/lib/rubocop/remote_config.rb +10 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f038acc03307acfc14ddf1dd971bf78978fac3401b4588b78b6bab4f4b7d8e13
|
4
|
+
data.tar.gz: 4f5da9053cce2f82b955f15d311d4b0d1f78396b2d49c8672c27d380804d5ba8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c4b743259b607ed588066f260b69cfdfd03772cd89f533eaf80705e689005a771ef76cf29873d73c0e5f97e3b7b4be6e6080a5890a63ebb19150d951ae272e1
|
7
|
+
data.tar.gz: 7505601eb0e34cc563cb8b7efdec9b6340e709f6a29eec7a7b952f84386df60fe8912b8ebd0849d9ba59e22e7701b980276f8bd728330985d5fa9bdf99c2d9ad
|
data/README.md
CHANGED
@@ -54,7 +54,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
54
54
|
in your `Gemfile`:
|
55
55
|
|
56
56
|
```rb
|
57
|
-
gem 'rubocop', '~> 1.
|
57
|
+
gem 'rubocop', '~> 1.17', require: false
|
58
58
|
```
|
59
59
|
|
60
60
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -24,6 +24,7 @@ module RuboCop
|
|
24
24
|
# method
|
25
25
|
class DotPosition < Base
|
26
26
|
include ConfigurableEnforcedStyle
|
27
|
+
include RangeHelp
|
27
28
|
extend AutoCorrector
|
28
29
|
|
29
30
|
def on_send(node)
|
@@ -42,7 +43,12 @@ module RuboCop
|
|
42
43
|
private
|
43
44
|
|
44
45
|
def autocorrect(corrector, dot, node)
|
45
|
-
|
46
|
+
dot_range = if processed_source[dot.line - 1].strip == '.'
|
47
|
+
range_by_whole_lines(dot, include_final_newline: true)
|
48
|
+
else
|
49
|
+
dot
|
50
|
+
end
|
51
|
+
corrector.remove(dot_range)
|
46
52
|
case style
|
47
53
|
when :leading
|
48
54
|
corrector.insert_before(selector_range(node), dot.source)
|
@@ -45,8 +45,7 @@ module RuboCop
|
|
45
45
|
def on_if(node)
|
46
46
|
return if correct_style?(node)
|
47
47
|
|
48
|
-
if node.modifier_form? &&
|
49
|
-
heredoc_node = last_heredoc_argument(node)
|
48
|
+
if node.modifier_form? && (heredoc_node = last_heredoc_argument(node))
|
50
49
|
return if next_line_empty_or_enable_directive_comment?(heredoc_line(node, heredoc_node))
|
51
50
|
|
52
51
|
add_offense(heredoc_node.loc.heredoc_end) do |corrector|
|
@@ -62,7 +61,7 @@ module RuboCop
|
|
62
61
|
private
|
63
62
|
|
64
63
|
def autocorrect(corrector, node)
|
65
|
-
node_range = if
|
64
|
+
node_range = if heredoc?(node)
|
66
65
|
range_by_whole_lines(node.loc.heredoc_body)
|
67
66
|
else
|
68
67
|
range_by_whole_lines(node.source_range)
|
@@ -125,19 +124,8 @@ module RuboCop
|
|
125
124
|
next_sibling.if_type? && contains_guard_clause?(next_sibling)
|
126
125
|
end
|
127
126
|
|
128
|
-
def last_argument_is_heredoc?(node)
|
129
|
-
last_children = node.if_branch
|
130
|
-
return false unless last_children&.send_type?
|
131
|
-
|
132
|
-
heredoc?(last_heredoc_argument(node))
|
133
|
-
end
|
134
|
-
|
135
127
|
def last_heredoc_argument(node)
|
136
|
-
n =
|
137
|
-
node.if_branch.children.last
|
138
|
-
else
|
139
|
-
node
|
140
|
-
end
|
128
|
+
n = last_heredoc_argument_node(node)
|
141
129
|
|
142
130
|
return n if heredoc?(n)
|
143
131
|
return unless n.respond_to?(:arguments)
|
@@ -150,6 +138,16 @@ module RuboCop
|
|
150
138
|
return last_heredoc_argument(n.receiver) if n.respond_to?(:receiver)
|
151
139
|
end
|
152
140
|
|
141
|
+
def last_heredoc_argument_node(node)
|
142
|
+
return node unless node.respond_to?(:if_branch)
|
143
|
+
|
144
|
+
if node.if_branch.and_type?
|
145
|
+
node.if_branch.children.first
|
146
|
+
else
|
147
|
+
node.if_branch.children.last
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
153
151
|
def heredoc_line(node, heredoc_node)
|
154
152
|
heredoc_body = heredoc_node.loc.heredoc_body
|
155
153
|
num_of_heredoc_lines = heredoc_body.last_line - heredoc_body.first_line
|
@@ -138,6 +138,14 @@ module RuboCop
|
|
138
138
|
check_indentation(case_node.when_branches.last.loc.keyword, case_node.else_branch)
|
139
139
|
end
|
140
140
|
|
141
|
+
def on_case_match(case_match)
|
142
|
+
case_match.each_in_pattern do |in_pattern_node|
|
143
|
+
check_indentation(in_pattern_node.loc.keyword, in_pattern_node.body)
|
144
|
+
end
|
145
|
+
|
146
|
+
check_indentation(case_match.in_pattern_branches.last.loc.keyword, case_match.else_branch)
|
147
|
+
end
|
148
|
+
|
141
149
|
def on_if(node, base = node)
|
142
150
|
return if ignored_node?(node)
|
143
151
|
return if node.ternary? || node.modifier_form?
|
@@ -42,8 +42,9 @@ module RuboCop
|
|
42
42
|
# # good
|
43
43
|
# foo(a) { |x| puts x }
|
44
44
|
#
|
45
|
-
class RedundantLineBreak <
|
45
|
+
class RedundantLineBreak < Base
|
46
46
|
include CheckAssignment
|
47
|
+
extend AutoCorrector
|
47
48
|
|
48
49
|
MSG = 'Redundant line break detected.'
|
49
50
|
|
@@ -55,23 +56,24 @@ module RuboCop
|
|
55
56
|
|
56
57
|
return unless offense?(node) && !part_of_ignored_node?(node)
|
57
58
|
|
58
|
-
|
59
|
-
ignore_node(node)
|
59
|
+
register_offense(node)
|
60
60
|
end
|
61
61
|
|
62
|
+
private
|
63
|
+
|
62
64
|
def check_assignment(node, _rhs)
|
63
65
|
return unless offense?(node)
|
64
66
|
|
65
|
-
|
66
|
-
ignore_node(node)
|
67
|
+
register_offense(node)
|
67
68
|
end
|
68
69
|
|
69
|
-
def
|
70
|
-
|
70
|
+
def register_offense(node)
|
71
|
+
add_offense(node) do |corrector|
|
72
|
+
corrector.replace(node.source_range, to_single_line(node.source).strip)
|
73
|
+
end
|
74
|
+
ignore_node(node)
|
71
75
|
end
|
72
76
|
|
73
|
-
private
|
74
|
-
|
75
77
|
def offense?(node)
|
76
78
|
return false if configured_to_not_be_inspected?(node)
|
77
79
|
|
@@ -81,6 +81,18 @@ module RuboCop
|
|
81
81
|
check(node, %i[begin end].freeze, nil)
|
82
82
|
end
|
83
83
|
|
84
|
+
# Handle one-line pattern matching syntax (`in`) with `Parser::Ruby27`.
|
85
|
+
def on_match_pattern(node)
|
86
|
+
return if target_ruby_version >= 3.0
|
87
|
+
|
88
|
+
check(node, [:operator].freeze)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Handle one-line pattern matching syntax (`in`) with `Parser::Ruby30`.
|
92
|
+
def on_match_pattern_p(node)
|
93
|
+
check(node, [:operator].freeze)
|
94
|
+
end
|
95
|
+
|
84
96
|
def on_next(node)
|
85
97
|
check(node, [:keyword].freeze)
|
86
98
|
end
|
@@ -120,6 +120,12 @@ module RuboCop
|
|
120
120
|
check_operator(:special_asgn, node.loc.operator, right.source_range)
|
121
121
|
end
|
122
122
|
|
123
|
+
def on_match_pattern(node)
|
124
|
+
return if target_ruby_version < 3.0
|
125
|
+
|
126
|
+
check_operator(:match_pattern, node.loc.operator, node.source_range)
|
127
|
+
end
|
128
|
+
|
123
129
|
alias on_or on_binary
|
124
130
|
alias on_and on_binary
|
125
131
|
alias on_lvasgn on_assignment
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks for literals used as the conditions or as
|
7
7
|
# operands in and/or expressions serving as the conditions of
|
8
|
-
# if/while/until.
|
8
|
+
# if/while/until/case-when/case-in.
|
9
9
|
#
|
10
10
|
# @example
|
11
11
|
#
|
@@ -67,6 +67,18 @@ module RuboCop
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
def on_case_match(case_match_node)
|
71
|
+
if case_match_node.condition
|
72
|
+
check_case(case_match_node)
|
73
|
+
else
|
74
|
+
case_match_node.each_in_pattern do |in_pattern_node|
|
75
|
+
next unless in_pattern_node.condition.literal?
|
76
|
+
|
77
|
+
add_offense(in_pattern_node)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
70
82
|
def on_send(node)
|
71
83
|
return unless node.negation_method?
|
72
84
|
|
@@ -45,37 +45,52 @@ module RuboCop
|
|
45
45
|
class MissingCopEnableDirective < Base
|
46
46
|
include RangeHelp
|
47
47
|
|
48
|
-
MSG = 'Re-enable %<cop>s
|
49
|
-
MSG_BOUND = 'Re-enable %<cop>s
|
48
|
+
MSG = 'Re-enable %<cop>s %<type>s with `# rubocop:enable` after disabling it.'
|
49
|
+
MSG_BOUND = 'Re-enable %<cop>s %<type>s within %<max_range>s lines after disabling it.'
|
50
50
|
|
51
|
-
# rubocop:disable Metrics/AbcSize
|
52
51
|
def on_new_investigation
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
# the case when max_range is Float::INFINITY
|
58
|
-
next if line_range.max - line_range.min < max_range + 2
|
52
|
+
each_missing_enable do |cop, line_range|
|
53
|
+
# This has to remain a strict inequality to handle
|
54
|
+
# the case when max_range is Float::INFINITY
|
55
|
+
next if line_range.max - line_range.min < max_range + 2
|
59
56
|
|
60
|
-
|
57
|
+
range = source_range(processed_source.buffer, line_range.min, (0..0))
|
58
|
+
comment = processed_source.comment_at_line(line_range.begin)
|
61
59
|
|
62
|
-
|
63
|
-
end
|
60
|
+
add_offense(range, message: message(cop, comment))
|
64
61
|
end
|
65
62
|
end
|
66
|
-
# rubocop:enable Metrics/AbcSize
|
67
63
|
|
68
64
|
private
|
69
65
|
|
70
|
-
def
|
66
|
+
def each_missing_enable
|
67
|
+
processed_source.disabled_line_ranges.each do |cop, line_ranges|
|
68
|
+
line_ranges.each { |line_range| yield cop, line_range }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def max_range
|
73
|
+
@max_range ||= cop_config['MaximumRangeSize']
|
74
|
+
end
|
75
|
+
|
76
|
+
def message(cop, comment, type = 'cop')
|
77
|
+
if department_enabled?(cop, comment)
|
78
|
+
type = 'department'
|
79
|
+
cop = cop.split('/').first
|
80
|
+
end
|
81
|
+
|
71
82
|
if max_range == Float::INFINITY
|
72
|
-
format(MSG, cop: cop)
|
83
|
+
format(MSG, cop: cop, type: type)
|
73
84
|
else
|
74
|
-
format(MSG_BOUND, cop: cop, max_range: max_range)
|
85
|
+
format(MSG_BOUND, cop: cop, type: type, max_range: max_range)
|
75
86
|
end
|
76
87
|
end
|
88
|
+
|
89
|
+
def department_enabled?(cop, comment)
|
90
|
+
DirectiveComment.new(comment).in_directive_department?(cop)
|
91
|
+
end
|
77
92
|
end
|
78
93
|
end
|
79
94
|
end
|
80
95
|
end
|
81
|
-
# rubocop:enable Lint/RedundantCopDisableDirective
|
96
|
+
# rubocop:enable Lint/RedundantCopDisableDirective
|
@@ -25,11 +25,12 @@ module RuboCop
|
|
25
25
|
#
|
26
26
|
# # good
|
27
27
|
# x += 1
|
28
|
-
class RedundantCopDisableDirective < Base
|
28
|
+
class RedundantCopDisableDirective < Base # rubocop:todo Metrics/ClassLength
|
29
29
|
include RangeHelp
|
30
30
|
extend AutoCorrector
|
31
31
|
|
32
32
|
COP_NAME = 'Lint/RedundantCopDisableDirective'
|
33
|
+
DEPARTMENT_MARKER = 'DEPARTMENT'
|
33
34
|
|
34
35
|
attr_accessor :offenses_to_check
|
35
36
|
|
@@ -41,12 +42,9 @@ module RuboCop
|
|
41
42
|
def on_new_investigation
|
42
43
|
return unless offenses_to_check
|
43
44
|
|
44
|
-
cop_disabled_line_ranges = processed_source.disabled_line_ranges
|
45
|
-
|
46
45
|
redundant_cops = Hash.new { |h, k| h[k] = Set.new }
|
47
46
|
|
48
|
-
each_redundant_disable
|
49
|
-
offenses_to_check) do |comment, redundant_cop|
|
47
|
+
each_redundant_disable do |comment, redundant_cop|
|
50
48
|
redundant_cops[comment].add(redundant_cop)
|
51
49
|
end
|
52
50
|
|
@@ -56,6 +54,14 @@ module RuboCop
|
|
56
54
|
|
57
55
|
private
|
58
56
|
|
57
|
+
def cop_disabled_line_ranges
|
58
|
+
processed_source.disabled_line_ranges
|
59
|
+
end
|
60
|
+
|
61
|
+
def disabled_ranges
|
62
|
+
cop_disabled_line_ranges[COP_NAME] || [0..0]
|
63
|
+
end
|
64
|
+
|
59
65
|
def previous_line_blank?(range)
|
60
66
|
processed_source.buffer.source_line(range.line - 1).blank?
|
61
67
|
end
|
@@ -97,32 +103,34 @@ module RuboCop
|
|
97
103
|
range_with_surrounding_space(range: range, side: :right, newlines: false)
|
98
104
|
end
|
99
105
|
|
100
|
-
def each_redundant_disable(
|
101
|
-
&block)
|
102
|
-
disabled_ranges = cop_disabled_line_ranges[COP_NAME] || [0..0]
|
103
|
-
|
106
|
+
def each_redundant_disable(&block)
|
104
107
|
cop_disabled_line_ranges.each do |cop, line_ranges|
|
105
|
-
each_already_disabled(line_ranges,
|
106
|
-
|
107
|
-
each_line_range(line_ranges, disabled_ranges, offenses, cop, &block)
|
108
|
+
each_already_disabled(cop, line_ranges, &block)
|
109
|
+
each_line_range(cop, line_ranges, &block)
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
111
|
-
def each_line_range(
|
112
|
-
|
113
|
-
|
114
|
-
comment = processed_source.comment_at_line(line_range.begin)
|
115
|
-
next if ignore_offense?(disabled_ranges, line_range)
|
113
|
+
def each_line_range(cop, line_ranges)
|
114
|
+
line_ranges.each_with_index do |line_range, line_range_index|
|
115
|
+
next if ignore_offense?(line_range)
|
116
116
|
|
117
|
-
|
118
|
-
|
117
|
+
comment = processed_source.comment_at_line(line_range.begin)
|
118
|
+
redundant = if all_disabled?(comment)
|
119
|
+
find_redundant_all(line_range, line_ranges[line_range_index + 1])
|
120
|
+
elsif department_disabled?(cop, comment)
|
121
|
+
find_redundant_department(cop, line_range)
|
122
|
+
else
|
123
|
+
find_redundant_cop(cop, line_range)
|
124
|
+
end
|
125
|
+
|
126
|
+
yield comment, redundant if redundant
|
119
127
|
end
|
120
128
|
end
|
121
129
|
|
122
|
-
def each_already_disabled(
|
130
|
+
def each_already_disabled(cop, line_ranges)
|
123
131
|
line_ranges.each_cons(2) do |previous_range, range|
|
124
|
-
next if ignore_offense?(
|
125
|
-
next
|
132
|
+
next if ignore_offense?(range)
|
133
|
+
next unless followed_ranges?(previous_range, range)
|
126
134
|
|
127
135
|
# If a cop is disabled in a range that begins on the same line as
|
128
136
|
# the end of the previous range, it means that the cop was
|
@@ -133,42 +141,56 @@ module RuboCop
|
|
133
141
|
# Comments disabling all cops don't count since it's reasonable
|
134
142
|
# to disable a few select cops first and then all cops further
|
135
143
|
# down in the code.
|
136
|
-
yield comment if comment && !all_disabled?(comment)
|
144
|
+
yield comment, cop if comment && !all_disabled?(comment)
|
137
145
|
end
|
138
146
|
end
|
139
147
|
|
140
|
-
|
141
|
-
|
142
|
-
if
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
148
|
+
def find_redundant_cop(cop, range)
|
149
|
+
cop_offenses = offenses_to_check.select { |offense| offense.cop_name == cop }
|
150
|
+
cop if range_with_offense?(range, cop_offenses)
|
151
|
+
end
|
152
|
+
|
153
|
+
def find_redundant_all(range, next_range)
|
154
|
+
# If there's a disable all comment followed by a comment
|
155
|
+
# specifically disabling `cop`, we don't report the `all`
|
156
|
+
# comment. If the disable all comment is truly redundant, we will
|
157
|
+
# detect that when examining the comments of another cop, and we
|
158
|
+
# get the full line range for the disable all.
|
159
|
+
has_no_next_range = next_range.nil? || !followed_ranges?(range, next_range)
|
160
|
+
'all' if has_no_next_range && range_with_offense?(range)
|
161
|
+
end
|
162
|
+
|
163
|
+
def find_redundant_department(cop, range)
|
164
|
+
department = cop.split('/').first
|
165
|
+
offenses = offenses_to_check.select { |offense| offense.cop_name.start_with?(department) }
|
166
|
+
add_department_marker(department) if range_with_offense?(range, offenses)
|
167
|
+
end
|
168
|
+
|
169
|
+
def followed_ranges?(range, next_range)
|
170
|
+
range.end == next_range.begin
|
171
|
+
end
|
172
|
+
|
173
|
+
def range_with_offense?(range, offenses = offenses_to_check)
|
174
|
+
offenses.none? { |offense| range.cover?(offense.line) }
|
156
175
|
end
|
157
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
158
176
|
|
159
177
|
def all_disabled?(comment)
|
160
|
-
|
178
|
+
DirectiveComment.new(comment).disabled_all?
|
161
179
|
end
|
162
180
|
|
163
|
-
def ignore_offense?(
|
181
|
+
def ignore_offense?(line_range)
|
164
182
|
disabled_ranges.any? do |range|
|
165
183
|
range.cover?(line_range.min) && range.cover?(line_range.max)
|
166
184
|
end
|
167
185
|
end
|
168
186
|
|
187
|
+
def department_disabled?(cop, comment)
|
188
|
+
directive = DirectiveComment.new(comment)
|
189
|
+
directive.in_directive_department?(cop) && !directive.overridden_by_department?(cop)
|
190
|
+
end
|
191
|
+
|
169
192
|
def directive_count(comment)
|
170
|
-
|
171
|
-
cops_string.split(/,\s*/).size
|
193
|
+
DirectiveComment.new(comment).directive_count
|
172
194
|
end
|
173
195
|
|
174
196
|
def add_offenses(redundant_cops)
|
@@ -183,12 +205,9 @@ module RuboCop
|
|
183
205
|
|
184
206
|
def add_offense_for_entire_comment(comment, cops)
|
185
207
|
location = DirectiveComment.new(comment).range
|
186
|
-
|
208
|
+
cop_names = cops.sort.map { |c| describe(c) }.join(', ')
|
187
209
|
|
188
|
-
add_offense(
|
189
|
-
location,
|
190
|
-
message: "Unnecessary disabling of #{cop_list.join(', ')}."
|
191
|
-
) do |corrector|
|
210
|
+
add_offense(location, message: message(cop_names)) do |corrector|
|
192
211
|
range = comment_range_with_surrounding_space(location, comment.loc.expression)
|
193
212
|
corrector.remove(range)
|
194
213
|
end
|
@@ -200,10 +219,8 @@ module RuboCop
|
|
200
219
|
ranges = cop_ranges.map { |_, r| r }
|
201
220
|
|
202
221
|
cop_ranges.each do |cop, range|
|
203
|
-
|
204
|
-
|
205
|
-
message: "Unnecessary disabling of #{describe(cop)}."
|
206
|
-
) do |corrector|
|
222
|
+
cop_name = describe(cop)
|
223
|
+
add_offense(range, message: message(cop_name)) do |corrector|
|
207
224
|
range = directive_range_in_list(range, ranges)
|
208
225
|
corrector.remove(range)
|
209
226
|
end
|
@@ -211,6 +228,7 @@ module RuboCop
|
|
211
228
|
end
|
212
229
|
|
213
230
|
def cop_range(comment, cop)
|
231
|
+
cop = remove_department_marker(cop)
|
214
232
|
matching_range(comment.loc.expression, cop) ||
|
215
233
|
matching_range(comment.loc.expression, Badge.parse(cop).cop_name) ||
|
216
234
|
raise("Couldn't find #{cop} in comment: #{comment.text}")
|
@@ -233,18 +251,16 @@ module RuboCop
|
|
233
251
|
end
|
234
252
|
|
235
253
|
def describe(cop)
|
236
|
-
if cop == 'all'
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
end
|
247
|
-
end
|
254
|
+
return 'all cops' if cop == 'all'
|
255
|
+
return "`#{remove_department_marker(cop)}` department" if department_marker?(cop)
|
256
|
+
return "`#{cop}`" if all_cop_names.include?(cop)
|
257
|
+
|
258
|
+
similar = NameSimilarity.find_similar_name(cop, all_cop_names)
|
259
|
+
similar ? "`#{cop}` (did you mean `#{similar}`?)" : "`#{cop}` (unknown cop)"
|
260
|
+
end
|
261
|
+
|
262
|
+
def message(cop_names)
|
263
|
+
"Unnecessary disabling of #{cop_names}."
|
248
264
|
end
|
249
265
|
|
250
266
|
def all_cop_names
|
@@ -255,6 +271,18 @@ module RuboCop
|
|
255
271
|
line = range.source_buffer.source_line(range.last_line)
|
256
272
|
(line =~ /\s*\z/) == range.last_column
|
257
273
|
end
|
274
|
+
|
275
|
+
def department_marker?(department)
|
276
|
+
department.start_with?(DEPARTMENT_MARKER)
|
277
|
+
end
|
278
|
+
|
279
|
+
def remove_department_marker(department)
|
280
|
+
department.gsub(DEPARTMENT_MARKER, '')
|
281
|
+
end
|
282
|
+
|
283
|
+
def add_department_marker(department)
|
284
|
+
DEPARTMENT_MARKER + department
|
285
|
+
end
|
258
286
|
end
|
259
287
|
end
|
260
288
|
end
|
@@ -54,6 +54,7 @@ module RuboCop
|
|
54
54
|
directive = DirectiveComment.new(comment)
|
55
55
|
|
56
56
|
cop_names.each do |name|
|
57
|
+
name = name.split('/').first if department?(directive, name)
|
57
58
|
add_offense(
|
58
59
|
range_of_offense(comment, name),
|
59
60
|
message: format(MSG, cop: all_or_name(name))
|
@@ -119,6 +120,10 @@ module RuboCop
|
|
119
120
|
def all_or_name(name)
|
120
121
|
name == 'all' ? 'all cops' : name
|
121
122
|
end
|
123
|
+
|
124
|
+
def department?(directive, name)
|
125
|
+
directive.in_directive_department?(name) && !directive.overridden_by_department?(name)
|
126
|
+
end
|
122
127
|
end
|
123
128
|
end
|
124
129
|
end
|
@@ -61,7 +61,9 @@ module RuboCop
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def valid_content_token?(content_token)
|
64
|
-
/\W+/.match?(content_token) ||
|
64
|
+
/\W+/.match?(content_token) ||
|
65
|
+
DISABLING_COPS_CONTENT_TOKEN.match?(content_token) ||
|
66
|
+
Registry.global.department?(content_token)
|
65
67
|
end
|
66
68
|
|
67
69
|
def contain_unexpected_character_for_department_name?(name)
|
@@ -67,6 +67,28 @@ module RuboCop
|
|
67
67
|
# do_x
|
68
68
|
# do_z
|
69
69
|
# end
|
70
|
+
#
|
71
|
+
# # bad
|
72
|
+
# case foo
|
73
|
+
# in 1
|
74
|
+
# do_x
|
75
|
+
# in 2
|
76
|
+
# do_x
|
77
|
+
# else
|
78
|
+
# do_x
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# # good
|
82
|
+
# case foo
|
83
|
+
# in 1
|
84
|
+
# do_x
|
85
|
+
# do_y
|
86
|
+
# in 2
|
87
|
+
# # nothing
|
88
|
+
# else
|
89
|
+
# do_x
|
90
|
+
# do_z
|
91
|
+
# end
|
70
92
|
class IdenticalConditionalBranches < Base
|
71
93
|
include RangeHelp
|
72
94
|
extend AutoCorrector
|
@@ -87,6 +109,13 @@ module RuboCop
|
|
87
109
|
check_branches(node, branches)
|
88
110
|
end
|
89
111
|
|
112
|
+
def on_case_match(node)
|
113
|
+
return unless node.else? && node.else_branch
|
114
|
+
|
115
|
+
branches = node.in_pattern_branches.map(&:body).push(node.else_branch)
|
116
|
+
check_branches(node, branches)
|
117
|
+
end
|
118
|
+
|
90
119
|
private
|
91
120
|
|
92
121
|
def check_branches(node, branches)
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
# # good
|
24
24
|
# raise StandardError, 'message'
|
25
25
|
# fail 'message'
|
26
|
+
# raise MyCustomError
|
26
27
|
# raise MyCustomError.new(arg1, arg2, arg3)
|
27
28
|
# raise MyKwArgError.new(key1: val1, key2: val2)
|
28
29
|
#
|
@@ -37,6 +38,7 @@ module RuboCop
|
|
37
38
|
#
|
38
39
|
# # good
|
39
40
|
# raise StandardError.new('message')
|
41
|
+
# raise MyCustomError
|
40
42
|
# raise MyCustomError.new(arg1, arg2, arg3)
|
41
43
|
# fail 'message'
|
42
44
|
class RaiseArgs < Base
|
@@ -117,7 +117,7 @@ module RuboCop
|
|
117
117
|
def allowed_percent_r_literal?(node)
|
118
118
|
style == :slashes && contains_disallowed_slash?(node) ||
|
119
119
|
style == :percent_r ||
|
120
|
-
allowed_mixed_percent_r?(node)
|
120
|
+
allowed_mixed_percent_r?(node) || omit_parentheses_style?(node)
|
121
121
|
end
|
122
122
|
|
123
123
|
def allowed_mixed_percent_r?(node)
|
@@ -149,6 +149,14 @@ module RuboCop
|
|
149
149
|
config.for_cop('Style/PercentLiteralDelimiters') ['PreferredDelimiters']['%r'].chars
|
150
150
|
end
|
151
151
|
|
152
|
+
def omit_parentheses_style?(node)
|
153
|
+
return false unless node.parent&.call_type?
|
154
|
+
|
155
|
+
enforced_style = config.for_cop('Style/MethodCallWithArgsParentheses')['EnforcedStyle']
|
156
|
+
|
157
|
+
enforced_style == 'omit_parentheses'
|
158
|
+
end
|
159
|
+
|
152
160
|
def correct_delimiters(node, corrector)
|
153
161
|
replacement = calculate_replacement(node)
|
154
162
|
corrector.replace(node.loc.begin, replacement.first)
|
@@ -6,7 +6,9 @@ module RuboCop
|
|
6
6
|
# cops it contains.
|
7
7
|
class DirectiveComment
|
8
8
|
# @api private
|
9
|
-
|
9
|
+
REDUNDANT_DIRECTIVE_COP_DEPARTMENT = 'Lint'
|
10
|
+
# @api private
|
11
|
+
REDUNDANT_DIRECTIVE_COP = "#{REDUNDANT_DIRECTIVE_COP_DEPARTMENT}/RedundantCopDisableDirective"
|
10
12
|
# @api private
|
11
13
|
COP_NAME_PATTERN = '([A-Z]\w+/)*(?:[A-Z]\w+)'
|
12
14
|
# @api private
|
@@ -23,10 +25,11 @@ module RuboCop
|
|
23
25
|
line.split(DIRECTIVE_COMMENT_REGEXP).first
|
24
26
|
end
|
25
27
|
|
26
|
-
attr_reader :comment, :mode, :cops
|
28
|
+
attr_reader :comment, :cop_registry, :mode, :cops
|
27
29
|
|
28
|
-
def initialize(comment)
|
30
|
+
def initialize(comment, cop_registry = Cop::Registry.global)
|
29
31
|
@comment = comment
|
32
|
+
@cop_registry = cop_registry
|
30
33
|
@mode, @cops = match_captures
|
31
34
|
end
|
32
35
|
|
@@ -68,6 +71,11 @@ module RuboCop
|
|
68
71
|
!disabled? && all_cops?
|
69
72
|
end
|
70
73
|
|
74
|
+
# Checks if this directive disables all cops
|
75
|
+
def disabled_all?
|
76
|
+
disabled? && all_cops?
|
77
|
+
end
|
78
|
+
|
71
79
|
# Checks if all cops specified in this directive
|
72
80
|
def all_cops?
|
73
81
|
cops == 'all'
|
@@ -78,6 +86,26 @@ module RuboCop
|
|
78
86
|
@cop_names ||= all_cops? ? all_cop_names : parsed_cop_names
|
79
87
|
end
|
80
88
|
|
89
|
+
# Returns array of specified in this directive department names
|
90
|
+
# when all department disabled
|
91
|
+
def department_names
|
92
|
+
splitted_cops_string.select { |cop| department?(cop) }
|
93
|
+
end
|
94
|
+
|
95
|
+
# Checks if directive departments include cop
|
96
|
+
def in_directive_department?(cop)
|
97
|
+
department_names.any? { |department| cop.start_with?(department) }
|
98
|
+
end
|
99
|
+
|
100
|
+
# Checks if cop department has already used in directive comment
|
101
|
+
def overridden_by_department?(cop)
|
102
|
+
in_directive_department?(cop) && splitted_cops_string.include?(cop)
|
103
|
+
end
|
104
|
+
|
105
|
+
def directive_count
|
106
|
+
splitted_cops_string.count
|
107
|
+
end
|
108
|
+
|
81
109
|
# Returns line number for directive
|
82
110
|
def line_number
|
83
111
|
comment.loc.expression.line
|
@@ -85,12 +113,32 @@ module RuboCop
|
|
85
113
|
|
86
114
|
private
|
87
115
|
|
88
|
-
def
|
116
|
+
def splitted_cops_string
|
89
117
|
(cops || '').split(/,\s*/)
|
90
118
|
end
|
91
119
|
|
120
|
+
def parsed_cop_names
|
121
|
+
splitted_cops_string.map do |name|
|
122
|
+
department?(name) ? cop_names_for_department(name) : name
|
123
|
+
end.flatten
|
124
|
+
end
|
125
|
+
|
126
|
+
def department?(name)
|
127
|
+
cop_registry.department?(name)
|
128
|
+
end
|
129
|
+
|
92
130
|
def all_cop_names
|
93
|
-
|
131
|
+
exclude_redundant_directive_cop(cop_registry.names)
|
132
|
+
end
|
133
|
+
|
134
|
+
def cop_names_for_department(department)
|
135
|
+
names = cop_registry.names_for_department(department)
|
136
|
+
has_redundant_directive_cop = department == REDUNDANT_DIRECTIVE_COP_DEPARTMENT
|
137
|
+
has_redundant_directive_cop ? exclude_redundant_directive_cop(names) : names
|
138
|
+
end
|
139
|
+
|
140
|
+
def exclude_redundant_directive_cop(cops)
|
141
|
+
cops - [REDUNDANT_DIRECTIVE_COP]
|
94
142
|
end
|
95
143
|
end
|
96
144
|
end
|
@@ -55,6 +55,7 @@ module RuboCop
|
|
55
55
|
def generate_request(uri)
|
56
56
|
request = Net::HTTP::Get.new(uri.request_uri)
|
57
57
|
|
58
|
+
request.basic_auth(uri.user, uri.password) if uri.user
|
58
59
|
request['If-Modified-Since'] = File.stat(cache_path).mtime.rfc2822 if cache_path_exists?
|
59
60
|
|
60
61
|
yield request
|
@@ -70,7 +71,7 @@ module RuboCop
|
|
70
71
|
begin
|
71
72
|
response.error!
|
72
73
|
rescue StandardError => e
|
73
|
-
message = "#{e.message} while downloading remote config file #{
|
74
|
+
message = "#{e.message} while downloading remote config file #{cloned_url}"
|
74
75
|
raise e, message
|
75
76
|
end
|
76
77
|
end
|
@@ -94,9 +95,16 @@ module RuboCop
|
|
94
95
|
end
|
95
96
|
|
96
97
|
def cache_name_from_uri
|
97
|
-
uri =
|
98
|
+
uri = cloned_url
|
98
99
|
uri.query = nil
|
99
100
|
uri.to_s.gsub!(/[^0-9A-Za-z]/, '-')
|
100
101
|
end
|
102
|
+
|
103
|
+
def cloned_url
|
104
|
+
uri = @uri.clone
|
105
|
+
uri.user = nil if uri.user
|
106
|
+
uri.password = nil if uri.password
|
107
|
+
uri
|
108
|
+
end
|
101
109
|
end
|
102
110
|
end
|
data/lib/rubocop/version.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
8
8
|
- Jonas Arvidsson
|
9
9
|
- Yuji Nakayama
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-06-
|
13
|
+
date: 2021-06-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -881,9 +881,9 @@ metadata:
|
|
881
881
|
homepage_uri: https://rubocop.org/
|
882
882
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
883
883
|
source_code_uri: https://github.com/rubocop/rubocop/
|
884
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
884
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.17/
|
885
885
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
886
|
-
post_install_message:
|
886
|
+
post_install_message:
|
887
887
|
rdoc_options: []
|
888
888
|
require_paths:
|
889
889
|
- lib
|
@@ -898,8 +898,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
898
898
|
- !ruby/object:Gem::Version
|
899
899
|
version: '0'
|
900
900
|
requirements: []
|
901
|
-
rubygems_version: 3.
|
902
|
-
signing_key:
|
901
|
+
rubygems_version: 3.2.18
|
902
|
+
signing_key:
|
903
903
|
specification_version: 4
|
904
904
|
summary: Automatic Ruby code style checking tool.
|
905
905
|
test_files: []
|