rubocop 1.16.1 → 1.17.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 +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: []
|