rubocop 1.59.0 → 1.60.1
Sign up to get free protection for your applications and to get access to all the features.
- 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