rubocop 1.59.0 → 1.60.1
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/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/config/default.yml +3 -1
- data/lib/rubocop/config.rb +0 -2
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_validator.rb +0 -2
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +16 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +12 -5
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/naming/block_forwarding.rb +10 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +52 -11
- data/lib/rubocop/cop/style/collection_compact.rb +11 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/eval_with_location.rb +0 -11
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +39 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +9 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +13 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -3
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +8 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -2
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
- data/lib/rubocop/cops_documentation_generator.rb +11 -1
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +1 -1
- data/lib/rubocop/options.rb +0 -8
- data/lib/rubocop/rspec/shared_contexts.rb +6 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/server/cache.rb +1 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +11 -11
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -37,8 +37,8 @@ module RuboCop
|
|
37
37
|
MSG = 'Pass a block to `to_h` instead of calling `%<method>s%<dot>sto_h`.'
|
38
38
|
RESTRICT_ON_SEND = %i[to_h].freeze
|
39
39
|
|
40
|
-
# @!method map_to_h
|
41
|
-
def_node_matcher :map_to_h
|
40
|
+
# @!method map_to_h(node)
|
41
|
+
def_node_matcher :map_to_h, <<~PATTERN
|
42
42
|
{
|
43
43
|
$(call ({block numblock} $(call _ {:map :collect}) ...) :to_h)
|
44
44
|
$(call $(call _ {:map :collect} (block_pass sym)) :to_h)
|
@@ -50,9 +50,9 @@ module RuboCop
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def on_send(node)
|
53
|
-
return unless (to_h_node, map_node = map_to_h
|
53
|
+
return unless (to_h_node, map_node = map_to_h(node))
|
54
54
|
|
55
|
-
message = format(MSG, method: map_node.loc.selector.source, dot:
|
55
|
+
message = format(MSG, method: map_node.loc.selector.source, dot: to_h_node.loc.dot.source)
|
56
56
|
add_offense(map_node.loc.selector, message: message) do |corrector|
|
57
57
|
# If the `to_h` call already has a block, do not autocorrect.
|
58
58
|
next if to_h_node.block_node
|
@@ -64,13 +64,17 @@ module RuboCop
|
|
64
64
|
|
65
65
|
private
|
66
66
|
|
67
|
+
# rubocop:disable Metrics/AbcSize
|
67
68
|
def autocorrect(corrector, to_h, map)
|
68
69
|
removal_range = range_between(to_h.loc.dot.begin_pos, to_h.loc.selector.end_pos)
|
69
70
|
|
70
71
|
corrector.remove(range_with_surrounding_space(removal_range, side: :left))
|
71
|
-
|
72
|
+
if (map_dot = map.loc.dot)
|
73
|
+
corrector.replace(map_dot, to_h.loc.dot.source)
|
74
|
+
end
|
72
75
|
corrector.replace(map.loc.selector, 'to_h')
|
73
76
|
end
|
77
|
+
# rubocop:enable Metrics/AbcSize
|
74
78
|
end
|
75
79
|
end
|
76
80
|
end
|
@@ -127,23 +127,31 @@ module RuboCop
|
|
127
127
|
|
128
128
|
def call_with_ambiguous_arguments?(node) # rubocop:disable Metrics/PerceivedComplexity
|
129
129
|
call_with_braced_block?(node) ||
|
130
|
+
call_in_argument_with_block?(node) ||
|
130
131
|
call_as_argument_or_chain?(node) ||
|
131
132
|
call_in_match_pattern?(node) ||
|
132
133
|
hash_literal_in_arguments?(node) ||
|
133
134
|
node.descendants.any? do |n|
|
134
|
-
n.forwarded_args_type? ||
|
135
|
-
|
135
|
+
n.forwarded_args_type? || n.block_type? ||
|
136
|
+
ambiguous_literal?(n) || logical_operator?(n)
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
139
140
|
def call_with_braced_block?(node)
|
140
|
-
(node.
|
141
|
+
(node.call_type? || node.super_type?) && node.block_node&.braces?
|
142
|
+
end
|
143
|
+
|
144
|
+
def call_in_argument_with_block?(node)
|
145
|
+
parent = node.parent&.block_type? && node.parent&.parent
|
146
|
+
return false unless parent
|
147
|
+
|
148
|
+
parent.call_type? || parent.super_type? || parent.yield_type?
|
141
149
|
end
|
142
150
|
|
143
151
|
def call_as_argument_or_chain?(node)
|
144
152
|
node.parent &&
|
145
|
-
(
|
146
|
-
|
153
|
+
(node.parent.call_type? || node.parent.super_type? || node.parent.yield_type?) &&
|
154
|
+
!assigned_before?(node.parent, node)
|
147
155
|
end
|
148
156
|
|
149
157
|
def call_in_match_pattern?(node)
|
@@ -218,15 +218,13 @@ module RuboCop
|
|
218
218
|
send(style, node) # call require_parentheses or omit_parentheses
|
219
219
|
end
|
220
220
|
alias on_csend on_send
|
221
|
-
alias on_super on_send
|
222
221
|
alias on_yield on_send
|
223
222
|
|
224
223
|
private
|
225
224
|
|
226
225
|
def args_begin(node)
|
227
226
|
loc = node.loc
|
228
|
-
selector =
|
229
|
-
node.super_type? || node.yield_type? ? loc.keyword : loc.selector
|
227
|
+
selector = node.yield_type? ? loc.keyword : loc.selector
|
230
228
|
|
231
229
|
resize_by = args_parenthesized?(node) ? 2 : 1
|
232
230
|
selector.end.resize(resize_by)
|
@@ -54,12 +54,10 @@ module RuboCop
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def offense?(node)
|
57
|
-
node.ternary? && node.multiline?
|
57
|
+
node.ternary? && node.multiline? && node.source != replacement(node)
|
58
58
|
end
|
59
59
|
|
60
60
|
def autocorrect(corrector, node)
|
61
|
-
return unless offense?(node)
|
62
|
-
|
63
61
|
corrector.replace(node, replacement(node))
|
64
62
|
return unless (parent = node.parent)
|
65
63
|
return unless (comments_in_condition = comments_in_condition(node))
|
@@ -81,6 +81,7 @@ module RuboCop
|
|
81
81
|
cond = node.condition
|
82
82
|
|
83
83
|
control_op_condition(cond) do |first_child, rest_children|
|
84
|
+
return if require_parentheses?(node, first_child)
|
84
85
|
return if semicolon_separated_expressions?(first_child, rest_children)
|
85
86
|
return if modifier_op?(first_child)
|
86
87
|
return if parens_allowed?(cond)
|
@@ -92,6 +93,13 @@ module RuboCop
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
96
|
+
def require_parentheses?(node, condition_body)
|
97
|
+
return false if !node.while_type? && !node.until_type?
|
98
|
+
return false if !condition_body.block_type? && !condition_body.numblock_type?
|
99
|
+
|
100
|
+
condition_body.send_node.block_literal? && condition_body.keywords?
|
101
|
+
end
|
102
|
+
|
95
103
|
def semicolon_separated_expressions?(first_exp, rest_exps)
|
96
104
|
return false unless (second_exp = rest_exps.first)
|
97
105
|
|
@@ -56,6 +56,7 @@ module RuboCop
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
59
|
+
alias on_csend on_send
|
59
60
|
|
60
61
|
private
|
61
62
|
|
@@ -64,7 +65,7 @@ module RuboCop
|
|
64
65
|
return if node.last_argument&.block_pass_type?
|
65
66
|
|
66
67
|
if node.method?(:each) && !node.parent&.block_type?
|
67
|
-
ancestor_node = node.each_ancestor(:send).detect do |ancestor|
|
68
|
+
ancestor_node = node.each_ancestor(:send, :csend).detect do |ancestor|
|
68
69
|
ancestor.receiver == node &&
|
69
70
|
(RESTRICT_ON_SEND.include?(ancestor.method_name) || ancestor.method?(:reverse_each))
|
70
71
|
end
|
@@ -83,10 +84,12 @@ module RuboCop
|
|
83
84
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
84
85
|
|
85
86
|
def range(node)
|
86
|
-
|
87
|
-
|
87
|
+
return node.selector unless node.method?(:each)
|
88
|
+
|
89
|
+
if node.parent.call_type?
|
90
|
+
node.selector.join(node.parent.loc.dot)
|
88
91
|
else
|
89
|
-
node.loc.selector
|
92
|
+
node.loc.dot.join(node.selector)
|
90
93
|
end
|
91
94
|
end
|
92
95
|
|
@@ -94,7 +94,8 @@ module RuboCop
|
|
94
94
|
!ends_with_backslash_without_comment?(range.source_line) ||
|
95
95
|
string_concatenation?(range.source_line) ||
|
96
96
|
start_with_arithmetic_operator?(processed_source[range.line]) ||
|
97
|
-
inside_string_literal_or_method_with_argument?(range)
|
97
|
+
inside_string_literal_or_method_with_argument?(range) ||
|
98
|
+
leading_dot_method_chain_with_blank_line?(range)
|
98
99
|
end
|
99
100
|
|
100
101
|
def ends_with_backslash_without_comment?(source_line)
|
@@ -113,6 +114,12 @@ module RuboCop
|
|
113
114
|
end
|
114
115
|
end
|
115
116
|
|
117
|
+
def leading_dot_method_chain_with_blank_line?(range)
|
118
|
+
return false unless range.source_line.strip.start_with?('.', '&.')
|
119
|
+
|
120
|
+
processed_source[range.line].strip.empty?
|
121
|
+
end
|
122
|
+
|
116
123
|
def redundant_line_continuation?(range)
|
117
124
|
return true unless (node = find_node_for_line(range.line))
|
118
125
|
return false if argument_newline?(node)
|
@@ -53,8 +53,8 @@ module RuboCop
|
|
53
53
|
def ignore_syntax?(node)
|
54
54
|
return false unless (parent = node.parent)
|
55
55
|
|
56
|
-
parent.while_post_type? || parent.until_post_type? ||
|
57
|
-
like_method_argument_parentheses?(parent)
|
56
|
+
parent.while_post_type? || parent.until_post_type? || parent.match_with_lvasgn_type? ||
|
57
|
+
like_method_argument_parentheses?(parent) || multiline_control_flow_statements?(node)
|
58
58
|
end
|
59
59
|
|
60
60
|
def allowed_expression?(node)
|
@@ -104,6 +104,13 @@ module RuboCop
|
|
104
104
|
!node.arithmetic_operation? && node.first_argument.begin_type?
|
105
105
|
end
|
106
106
|
|
107
|
+
def multiline_control_flow_statements?(node)
|
108
|
+
return false unless (parent = node.parent)
|
109
|
+
return false if parent.single_line?
|
110
|
+
|
111
|
+
parent.return_type? || parent.next_type? || parent.break_type?
|
112
|
+
end
|
113
|
+
|
107
114
|
def empty_parentheses?(node)
|
108
115
|
# Don't flag `()`
|
109
116
|
node.children.empty?
|
@@ -150,6 +157,8 @@ module RuboCop
|
|
150
157
|
return if begin_node.chained?
|
151
158
|
|
152
159
|
if node.and_type? || node.or_type?
|
160
|
+
return if node.semantic_operator? && begin_node.parent
|
161
|
+
return if node.multiline? && allow_in_multiline_conditions?
|
153
162
|
return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
|
154
163
|
return if begin_node.parent&.if_type? && begin_node.parent&.ternary?
|
155
164
|
|
@@ -165,6 +174,13 @@ module RuboCop
|
|
165
174
|
# @!method interpolation?(node)
|
166
175
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
167
176
|
|
177
|
+
def allow_in_multiline_conditions?
|
178
|
+
parentheses_around_condition_config = config.for_cop('Style/ParenthesesAroundCondition')
|
179
|
+
return false unless parentheses_around_condition_config['Enabled']
|
180
|
+
|
181
|
+
!!parentheses_around_condition_config['AllowInMultilineConditions']
|
182
|
+
end
|
183
|
+
|
168
184
|
def check_send(begin_node, node)
|
169
185
|
return check_unary(begin_node, node) if node.unary_operation?
|
170
186
|
|
@@ -3,8 +3,9 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks that arrays are sliced with
|
7
|
-
# `ary[start..-1]` on Ruby 2.6
|
6
|
+
# Checks that arrays are not sliced with the redundant `ary[0..-1]`, replacing it with `ary`,
|
7
|
+
# and ensures arrays are sliced with endless ranges instead of `ary[start..-1]` on Ruby 2.6+,
|
8
|
+
# and with beginless ranges instead of `ary[nil..end]` on Ruby 2.7+.
|
8
9
|
#
|
9
10
|
# @safety
|
10
11
|
# This cop is unsafe because `x..-1` and `x..` are only guaranteed to
|
@@ -21,29 +22,94 @@ module RuboCop
|
|
21
22
|
#
|
22
23
|
# @example
|
23
24
|
# # bad
|
24
|
-
# items[
|
25
|
+
# items[0..-1]
|
26
|
+
# items[0..nil]
|
27
|
+
# items[0...nil]
|
25
28
|
#
|
26
29
|
# # good
|
27
|
-
# items
|
30
|
+
# items
|
31
|
+
#
|
32
|
+
# # bad
|
33
|
+
# items[1..-1] # Ruby 2.6+
|
34
|
+
# items[1..nil] # Ruby 2.6+
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# items[1..] # Ruby 2.6+
|
38
|
+
#
|
39
|
+
# # bad
|
40
|
+
# items[nil..42] # Ruby 2.7+
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# items[..42] # Ruby 2.7+
|
44
|
+
# items[0..42] # Ruby 2.7+
|
45
|
+
#
|
28
46
|
class SlicingWithRange < Base
|
29
47
|
extend AutoCorrector
|
30
48
|
extend TargetRubyVersion
|
31
49
|
|
32
50
|
minimum_target_ruby_version 2.6
|
33
51
|
|
34
|
-
MSG = 'Prefer
|
52
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
|
53
|
+
MSG_USELESS_RANGE = 'Remove the useless `%<prefer>s`.'
|
35
54
|
RESTRICT_ON_SEND = %i[[]].freeze
|
36
55
|
|
56
|
+
# @!method range_from_zero_till_minus_one?(node)
|
57
|
+
def_node_matcher :range_from_zero_till_minus_one?, <<~PATTERN
|
58
|
+
{
|
59
|
+
(irange (int 0) {(int -1) nil})
|
60
|
+
(erange (int 0) nil)
|
61
|
+
}
|
62
|
+
PATTERN
|
63
|
+
|
37
64
|
# @!method range_till_minus_one?(node)
|
38
|
-
def_node_matcher :range_till_minus_one?,
|
65
|
+
def_node_matcher :range_till_minus_one?, <<~PATTERN
|
66
|
+
{
|
67
|
+
(irange !nil? {(int -1) nil})
|
68
|
+
(erange !nil? nil)
|
69
|
+
}
|
70
|
+
PATTERN
|
71
|
+
|
72
|
+
# @!method range_from_zero?(node)
|
73
|
+
def_node_matcher :range_from_zero?, <<~PATTERN
|
74
|
+
(irange nil !nil?)
|
75
|
+
PATTERN
|
39
76
|
|
40
77
|
def on_send(node)
|
41
|
-
return unless node.arguments.
|
42
|
-
return unless range_till_minus_one?(node.first_argument)
|
78
|
+
return unless node.arguments.one?
|
43
79
|
|
44
|
-
|
45
|
-
|
80
|
+
range_node = node.first_argument
|
81
|
+
selector = node.loc.selector
|
82
|
+
unless (message, removal_range = offense_message_with_removal_range(range_node, selector))
|
83
|
+
return
|
46
84
|
end
|
85
|
+
|
86
|
+
add_offense(selector, message: message) do |corrector|
|
87
|
+
corrector.remove(removal_range)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def offense_message_with_removal_range(range_node, selector)
|
94
|
+
if range_from_zero_till_minus_one?(range_node)
|
95
|
+
[format(MSG_USELESS_RANGE, prefer: selector.source), selector]
|
96
|
+
elsif range_till_minus_one?(range_node)
|
97
|
+
[
|
98
|
+
format(MSG, prefer: endless(range_node), current: selector.source), range_node.end
|
99
|
+
]
|
100
|
+
elsif range_from_zero?(range_node) && target_ruby_version >= 2.7
|
101
|
+
[
|
102
|
+
format(MSG, prefer: beginless(range_node), current: selector.source), range_node.begin
|
103
|
+
]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def endless(range_node)
|
108
|
+
"[#{range_node.begin.source}#{range_node.loc.operator.source}]"
|
109
|
+
end
|
110
|
+
|
111
|
+
def beginless(range_node)
|
112
|
+
"[#{range_node.loc.operator.source}#{range_node.end.source}]"
|
47
113
|
end
|
48
114
|
end
|
49
115
|
end
|
@@ -37,6 +37,42 @@ module RuboCop
|
|
37
37
|
# # ArgumentError: wrong number of arguments (given 1, expected 0)
|
38
38
|
# ----
|
39
39
|
#
|
40
|
+
# It is also unsafe because `Symbol#to_proc` does not work with
|
41
|
+
# `protected` methods which would otherwise be accessible.
|
42
|
+
#
|
43
|
+
# For example:
|
44
|
+
#
|
45
|
+
# [source,ruby]
|
46
|
+
# ----
|
47
|
+
# class Box
|
48
|
+
# def initialize
|
49
|
+
# @secret = rand
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# def normal_matches?(*others)
|
53
|
+
# others.map { |other| other.secret }.any?(secret)
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# def symbol_to_proc_matches?(*others)
|
57
|
+
# others.map(&:secret).any?(secret)
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# protected
|
61
|
+
#
|
62
|
+
# attr_reader :secret
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# boxes = [Box.new, Box.new]
|
66
|
+
# Box.new.normal_matches?(*boxes)
|
67
|
+
# # => false
|
68
|
+
# boxes.first.normal_matches?(*boxes)
|
69
|
+
# # => true
|
70
|
+
# Box.new.symbol_to_proc_matches?(*boxes)
|
71
|
+
# # => NoMethodError: protected method `secret' called for #<Box...>
|
72
|
+
# boxes.first.symbol_to_proc_matches?(*boxes)
|
73
|
+
# # => NoMethodError: protected method `secret' called for #<Box...>
|
74
|
+
# ----
|
75
|
+
#
|
40
76
|
# @example
|
41
77
|
# # bad
|
42
78
|
# something.map { |s| s.upcase }
|
@@ -251,9 +251,18 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
251
251
|
"\ninclude::../partials/#{filename}[]\n"
|
252
252
|
end
|
253
253
|
|
254
|
+
# rubocop:disable Metrics/MethodLength
|
254
255
|
def print_cops_of_department(department)
|
255
256
|
selected_cops = cops_of_department(department)
|
256
|
-
content =
|
257
|
+
content = +<<~HEADER
|
258
|
+
////
|
259
|
+
Do NOT edit this file by hand directly, as it is automatically generated.
|
260
|
+
|
261
|
+
Please make any necessary changes to the cop documentation within the source files themselves.
|
262
|
+
////
|
263
|
+
|
264
|
+
= #{department}
|
265
|
+
HEADER
|
257
266
|
selected_cops.each { |cop| content << print_cop_with_doc(cop) }
|
258
267
|
content << footer_for_department(department)
|
259
268
|
file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
|
@@ -262,6 +271,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
262
271
|
file.write("#{content.strip}\n")
|
263
272
|
end
|
264
273
|
end
|
274
|
+
# rubocop:enable Metrics/MethodLength
|
265
275
|
|
266
276
|
def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
267
277
|
cop_config = config.for_cop(cop)
|
@@ -54,10 +54,7 @@ module RuboCop
|
|
54
54
|
return enum_for(__method__, named: named) unless block_given?
|
55
55
|
|
56
56
|
parsed_tree&.traverse do |event, exp, _index|
|
57
|
-
yield(exp) if event
|
58
|
-
named == exp.respond_to?(:name) &&
|
59
|
-
exp.respond_to?(:capturing?) &&
|
60
|
-
exp.capturing?
|
57
|
+
yield(exp) if named_capturing?(exp, event, named)
|
61
58
|
end
|
62
59
|
|
63
60
|
self
|
@@ -65,6 +62,14 @@ module RuboCop
|
|
65
62
|
|
66
63
|
private
|
67
64
|
|
65
|
+
def named_capturing?(exp, event, named)
|
66
|
+
event == :enter &&
|
67
|
+
named == exp.respond_to?(:name) &&
|
68
|
+
!exp.text.start_with?('(?<=') &&
|
69
|
+
exp.respond_to?(:capturing?) &&
|
70
|
+
exp.capturing?
|
71
|
+
end
|
72
|
+
|
68
73
|
def with_interpolations_blanked
|
69
74
|
# Ignore the trailing regopt node
|
70
75
|
children[0...-1].map do |child|
|
@@ -30,7 +30,8 @@ module RuboCop
|
|
30
30
|
@files_with_offenses ||= {}
|
31
31
|
end
|
32
32
|
|
33
|
-
def file_started(_file,
|
33
|
+
def file_started(_file, options)
|
34
|
+
@config_for_pwd = options[:config_store].for_pwd
|
34
35
|
@exclude_limit_option = @options[:exclude_limit]
|
35
36
|
@exclude_limit = Integer(@exclude_limit_option ||
|
36
37
|
RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS)
|
@@ -115,9 +116,13 @@ module RuboCop
|
|
115
116
|
def set_max(cfg, cop_name)
|
116
117
|
return unless cfg[:exclude_limit]
|
117
118
|
|
118
|
-
|
119
|
-
|
120
|
-
if
|
119
|
+
max_set_in_user_config =
|
120
|
+
@config_for_pwd.for_cop(cop_name)['Max'] != default_config(cop_name)['Max']
|
121
|
+
if !max_set_in_user_config &&
|
122
|
+
# In case auto_gen_only_exclude is set, only modify the maximum if the files are not
|
123
|
+
# excluded one by one.
|
124
|
+
(!@options[:auto_gen_only_exclude] ||
|
125
|
+
@files_with_offenses[cop_name].size > @exclude_limit)
|
121
126
|
cfg.merge!(cfg[:exclude_limit])
|
122
127
|
end
|
123
128
|
|
@@ -192,8 +197,8 @@ module RuboCop
|
|
192
197
|
# 'Enabled' option will be put into file only if exclude
|
193
198
|
# limit is exceeded.
|
194
199
|
rejected_keys = ['Enabled']
|
195
|
-
rejected_keys <<
|
196
|
-
cfg.reject { |key|
|
200
|
+
rejected_keys << /\AEnforcedStyle\w*/ unless auto_gen_enforced_style?
|
201
|
+
cfg.reject { |key| include_or_match?(rejected_keys, key) }
|
197
202
|
end
|
198
203
|
|
199
204
|
def output_offending_files(output_buffer, cfg, cop_name)
|
@@ -262,6 +267,12 @@ module RuboCop
|
|
262
267
|
def no_exclude_limit?
|
263
268
|
@options[:no_exclude_limit] == false
|
264
269
|
end
|
270
|
+
|
271
|
+
# Returns true if the given arr include the given elm or if any of the
|
272
|
+
# given arr is a regexp that matches the given elm.
|
273
|
+
def include_or_match?(arr, elm)
|
274
|
+
arr.include?(elm) || arr.any? { |x| x.is_a?(Regexp) && x.match?(elm) }
|
275
|
+
end
|
265
276
|
end
|
266
277
|
end
|
267
278
|
end
|
data/lib/rubocop/formatter.rb
CHANGED
@@ -14,7 +14,7 @@ module RuboCop
|
|
14
14
|
require_relative 'formatter/emacs_style_formatter'
|
15
15
|
require_relative 'formatter/file_list_formatter'
|
16
16
|
require_relative 'formatter/fuubar_style_formatter'
|
17
|
-
require_relative 'formatter/
|
17
|
+
require_relative 'formatter/github_actions_formatter'
|
18
18
|
require_relative 'formatter/html_formatter'
|
19
19
|
require_relative 'formatter/json_formatter'
|
20
20
|
require_relative 'formatter/junit_formatter'
|
data/lib/rubocop/lsp/routes.rb
CHANGED
data/lib/rubocop/options.rb
CHANGED
@@ -364,10 +364,6 @@ module RuboCop
|
|
364
364
|
raise OptionArgumentError, '-C/--cache argument must be true or false'
|
365
365
|
end
|
366
366
|
|
367
|
-
if display_only_fail_level_offenses_with_autocorrect?
|
368
|
-
raise OptionArgumentError, '--autocorrect cannot be used with ' \
|
369
|
-
'--display-only-fail-level-offenses.'
|
370
|
-
end
|
371
367
|
validate_auto_gen_config
|
372
368
|
validate_autocorrect
|
373
369
|
validate_display_only_failed
|
@@ -460,10 +456,6 @@ module RuboCop
|
|
460
456
|
(@options[:only] & %w[Lint/RedundantCopDisableDirective RedundantCopDisableDirective]).any?
|
461
457
|
end
|
462
458
|
|
463
|
-
def display_only_fail_level_offenses_with_autocorrect?
|
464
|
-
@options.key?(:display_only_fail_level_offenses) && @options.key?(:autocorrect)
|
465
|
-
end
|
466
|
-
|
467
459
|
def except_syntax?
|
468
460
|
@options.key?(:except) && (@options[:except] & %w[Lint/Syntax Syntax]).any?
|
469
461
|
end
|
@@ -128,6 +128,12 @@ RSpec.shared_context 'mock console output' do
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
+
RSpec.shared_context 'lsp mode' do
|
132
|
+
before do
|
133
|
+
allow(cop).to receive(:lsp_mode?).and_return(true)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
131
137
|
RSpec.shared_context 'ruby 2.0' do
|
132
138
|
let(:ruby_version) { 2.0 }
|
133
139
|
end
|
@@ -13,6 +13,7 @@ RSpec.configure do |config|
|
|
13
13
|
config.include HostEnvironmentSimulatorHelper
|
14
14
|
config.include_context 'config', :config
|
15
15
|
config.include_context 'isolated environment', :isolated_environment
|
16
|
+
config.include_context 'lsp mode', :lsp_mode
|
16
17
|
config.include_context 'maintain registry', :restore_registry
|
17
18
|
config.include_context 'ruby 2.0', :ruby20
|
18
19
|
config.include_context 'ruby 2.1', :ruby21
|
data/lib/rubocop/server/cache.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'fileutils'
|
4
3
|
require 'pathname'
|
5
4
|
require_relative '../cache_config'
|
6
5
|
require_relative '../config_finder'
|
@@ -117,7 +116,7 @@ module RuboCop
|
|
117
116
|
|
118
117
|
def pid_running?
|
119
118
|
Process.kill(0, pid_path.read.to_i) == 1
|
120
|
-
rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES
|
119
|
+
rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EROFS
|
121
120
|
false
|
122
121
|
end
|
123
122
|
|
data/lib/rubocop/version.rb
CHANGED