rubocop 1.70.0 → 1.71.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/config/default.yml +17 -0
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +7 -7
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +5 -2
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +12 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +12 -17
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +7 -0
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -3
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_subset.rb +170 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -2
- data/lib/rubocop/cop/security/compound_hash.rb +1 -0
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +6 -19
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +3 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +1 -1
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -1
- data/lib/rubocop/cop/style/hash_except.rb +5 -131
- data/lib/rubocop/cop/style/hash_slice.rb +65 -0
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
- data/lib/rubocop/cop/style/open_struct_use.rb +4 -4
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +27 -10
- data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- data/lib/rubocop/cops_documentation_generator.rb +13 -13
- data/lib/rubocop/directive_comment.rb +9 -8
- data/lib/rubocop/options.rb +2 -1
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +3 -0
- metadata +9 -8
@@ -44,146 +44,20 @@ module RuboCop
|
|
44
44
|
# {foo: 1, bar: 2, baz: 3}.except(:bar)
|
45
45
|
#
|
46
46
|
class HashExcept < Base
|
47
|
-
include
|
47
|
+
include HashSubset
|
48
48
|
extend TargetRubyVersion
|
49
49
|
extend AutoCorrector
|
50
50
|
|
51
51
|
minimum_target_ruby_version 3.0
|
52
52
|
|
53
|
-
MSG = 'Use `%<prefer>s` instead.'
|
54
|
-
RESTRICT_ON_SEND = %i[reject select filter].freeze
|
55
|
-
|
56
|
-
SUBSET_METHODS = %i[== != eql? include?].freeze
|
57
|
-
ACTIVE_SUPPORT_SUBSET_METHODS = (SUBSET_METHODS + %i[in? exclude?]).freeze
|
58
|
-
|
59
|
-
# @!method block_with_first_arg_check?(node)
|
60
|
-
def_node_matcher :block_with_first_arg_check?, <<~PATTERN
|
61
|
-
(block
|
62
|
-
(call _ _)
|
63
|
-
(args
|
64
|
-
$(arg _key)
|
65
|
-
(arg _))
|
66
|
-
{
|
67
|
-
$(send
|
68
|
-
{(lvar _key) $_ _ | _ $_ (lvar _key)})
|
69
|
-
(send
|
70
|
-
$(send
|
71
|
-
{(lvar _key) $_ _ | _ $_ (lvar _key)}) :!)
|
72
|
-
})
|
73
|
-
PATTERN
|
74
|
-
|
75
|
-
def on_send(node)
|
76
|
-
block = node.parent
|
77
|
-
return unless extracts_hash_subset?(block) && semantically_except_method?(node, block)
|
78
|
-
|
79
|
-
except_key = except_key(block)
|
80
|
-
return unless safe_to_register_offense?(block, except_key)
|
81
|
-
|
82
|
-
range = offense_range(node)
|
83
|
-
preferred_method = "except(#{except_key_source(except_key)})"
|
84
|
-
|
85
|
-
add_offense(range, message: format(MSG, prefer: preferred_method)) do |corrector|
|
86
|
-
corrector.replace(range, preferred_method)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
alias on_csend on_send
|
90
|
-
|
91
53
|
private
|
92
54
|
|
93
|
-
def
|
94
|
-
|
95
|
-
return false unless supported_subset_method?(method)
|
96
|
-
|
97
|
-
case method
|
98
|
-
when :include?, :exclude?
|
99
|
-
send_node.first_argument.source == key_arg.source
|
100
|
-
when :in?
|
101
|
-
send_node.receiver.source == key_arg.source
|
102
|
-
else
|
103
|
-
true
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def supported_subset_method?(method)
|
109
|
-
if active_support_extensions_enabled?
|
110
|
-
ACTIVE_SUPPORT_SUBSET_METHODS.include?(method)
|
111
|
-
else
|
112
|
-
SUBSET_METHODS.include?(method)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def semantically_except_method?(node, block)
|
117
|
-
body, negated = extract_body_if_negated(block.body)
|
118
|
-
|
119
|
-
if node.method?('reject')
|
120
|
-
body.method?('==') || body.method?('eql?') || included?(body, negated)
|
121
|
-
else
|
122
|
-
body.method?('!=') || not_included?(body, negated)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def included?(body, negated)
|
127
|
-
if negated
|
128
|
-
body.method?('exclude?')
|
129
|
-
else
|
130
|
-
body.method?('include?') || body.method?('in?')
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def not_included?(body, negated)
|
135
|
-
included?(body, !negated)
|
136
|
-
end
|
137
|
-
|
138
|
-
def safe_to_register_offense?(block, except_key)
|
139
|
-
body = block.body
|
140
|
-
|
141
|
-
if body.method?('==') || body.method?('!=')
|
142
|
-
except_key.sym_type? || except_key.str_type?
|
143
|
-
else
|
144
|
-
true
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def extract_body_if_negated(body)
|
149
|
-
if body.method?('!')
|
150
|
-
[body.receiver, true]
|
151
|
-
else
|
152
|
-
[body, false]
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def except_key_source(key)
|
157
|
-
if key.array_type?
|
158
|
-
key = if key.percent_literal?
|
159
|
-
key.each_value.map { |v| decorate_source(v) }
|
160
|
-
else
|
161
|
-
key.each_value.map(&:source)
|
162
|
-
end
|
163
|
-
return key.join(', ')
|
164
|
-
end
|
165
|
-
|
166
|
-
key.literal? ? key.source : "*#{key.source}"
|
167
|
-
end
|
168
|
-
|
169
|
-
def decorate_source(value)
|
170
|
-
return ":\"#{value.source}\"" if value.dsym_type?
|
171
|
-
return "\"#{value.source}\"" if value.dstr_type?
|
172
|
-
return ":#{value.source}" if value.sym_type?
|
173
|
-
|
174
|
-
"'#{value.source}'"
|
175
|
-
end
|
176
|
-
|
177
|
-
def except_key(node)
|
178
|
-
key_arg = node.argument_list.first.source
|
179
|
-
body, = extract_body_if_negated(node.body)
|
180
|
-
lhs, _method_name, rhs = *body
|
181
|
-
|
182
|
-
lhs.source == key_arg ? rhs : lhs
|
55
|
+
def semantically_subset_method?(node)
|
56
|
+
semantically_except_method?(node)
|
183
57
|
end
|
184
58
|
|
185
|
-
def
|
186
|
-
|
59
|
+
def preferred_method_name
|
60
|
+
'except'
|
187
61
|
end
|
188
62
|
end
|
189
63
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods
|
7
|
+
# that can be replaced with `Hash#slice` method.
|
8
|
+
#
|
9
|
+
# This cop should only be enabled on Ruby version 2.5 or higher.
|
10
|
+
# (`Hash#slice` was added in Ruby 2.5.)
|
11
|
+
#
|
12
|
+
# For safe detection, it is limited to commonly used string and symbol comparisons
|
13
|
+
# when using `==` or `!=`.
|
14
|
+
#
|
15
|
+
# This cop doesn't check for `Hash#delete_if` and `Hash#keep_if` because they
|
16
|
+
# modify the receiver.
|
17
|
+
#
|
18
|
+
# @safety
|
19
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
20
|
+
# is a `Hash` or responds to the replacement method.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k == :bar }
|
26
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| k != :bar }
|
27
|
+
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| k == :bar }
|
28
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k.eql?(:bar) }
|
29
|
+
#
|
30
|
+
# # bad
|
31
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| %i[bar].include?(k) }
|
32
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| !%i[bar].include?(k) }
|
33
|
+
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| %i[bar].include?(k) }
|
34
|
+
#
|
35
|
+
# # bad
|
36
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[bar].exclude?(k) }
|
37
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| %i[bar].exclude?(k) }
|
38
|
+
#
|
39
|
+
# # bad
|
40
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k.in?(%i[bar]) }
|
41
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| !k.in?(%i[bar]) }
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# {foo: 1, bar: 2, baz: 3}.slice(:bar)
|
45
|
+
#
|
46
|
+
class HashSlice < Base
|
47
|
+
include HashSubset
|
48
|
+
extend TargetRubyVersion
|
49
|
+
extend AutoCorrector
|
50
|
+
|
51
|
+
minimum_target_ruby_version 2.5
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def semantically_subset_method?(node)
|
56
|
+
semantically_slice_method?(node)
|
57
|
+
end
|
58
|
+
|
59
|
+
def preferred_method_name
|
60
|
+
'slice'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -33,8 +33,8 @@ module RuboCop
|
|
33
33
|
# @!method map_to_set?(node)
|
34
34
|
def_node_matcher :map_to_set?, <<~PATTERN
|
35
35
|
{
|
36
|
-
$(
|
37
|
-
$(
|
36
|
+
$(call ({block numblock} $(call _ {:map :collect}) ...) :to_set)
|
37
|
+
$(call $(call _ {:map :collect} (block_pass sym)) :to_set)
|
38
38
|
}
|
39
39
|
PATTERN
|
40
40
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
49
49
|
autocorrect(corrector, to_set_node, map_node)
|
50
50
|
end
|
51
51
|
end
|
52
|
+
alias on_csend on_send
|
52
53
|
|
53
54
|
private
|
54
55
|
|
@@ -45,6 +45,7 @@ module RuboCop
|
|
45
45
|
register_offense(node)
|
46
46
|
end
|
47
47
|
# rubocop:enable Metrics/CyclomaticComplexity
|
48
|
+
alias on_csend on_send
|
48
49
|
|
49
50
|
private
|
50
51
|
|
@@ -100,7 +101,7 @@ module RuboCop
|
|
100
101
|
# `obj.method ||= value` parses as (or-asgn (send ...) ...)
|
101
102
|
# which IS an `asgn_node`. Similarly, `obj.method += value` parses
|
102
103
|
# as (op-asgn (send ...) ...), which is also an `asgn_node`.
|
103
|
-
next if asgn_node.shorthand_asgn? && asgn_node.lhs.
|
104
|
+
next if asgn_node.shorthand_asgn? && asgn_node.lhs.call_type?
|
104
105
|
|
105
106
|
yield asgn_node
|
106
107
|
end
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
# acceptable value other than none, it will suppress the offenses
|
20
20
|
# raised by this cop. It enforces frozen state.
|
21
21
|
#
|
22
|
-
# NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
|
22
|
+
# NOTE: `Regexp` and `Range` literals are frozen objects since Ruby 3.0.
|
23
23
|
#
|
24
24
|
# NOTE: From Ruby 3.0, interpolated strings are not frozen when
|
25
25
|
# `# frozen-string-literal: true` is used, so this cop enforces explicit
|
@@ -3,15 +3,15 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Flags uses of OpenStruct
|
6
|
+
# Flags uses of `OpenStruct`, as it is now officially discouraged
|
7
7
|
# to be used for performance, version compatibility, and potential security issues.
|
8
8
|
#
|
9
9
|
# @safety
|
10
|
-
#
|
11
10
|
# Note that this cop may flag false positives; for instance, the following legal
|
12
11
|
# use of a hand-rolled `OpenStruct` type would be considered an offense:
|
13
12
|
#
|
14
|
-
#
|
13
|
+
# [source,ruby]
|
14
|
+
# -----
|
15
15
|
# module MyNamespace
|
16
16
|
# class OpenStruct # not the OpenStruct we're looking for
|
17
17
|
# end
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
# OpenStruct.new # resolves to MyNamespace::OpenStruct
|
21
21
|
# end
|
22
22
|
# end
|
23
|
-
#
|
23
|
+
# -----
|
24
24
|
#
|
25
25
|
# @example
|
26
26
|
#
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
14
14
|
# passed multiple arguments.
|
15
15
|
#
|
16
16
|
# The exploded style has an `AllowedCompactTypes` configuration
|
17
|
-
# option that takes an Array of exception name Strings.
|
17
|
+
# option that takes an `Array` of exception name Strings.
|
18
18
|
#
|
19
19
|
# @safety
|
20
20
|
# This cop is unsafe because `raise Foo` calls `Foo.exception`, not `Foo.new`.
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Check for uses of `Object#freeze` on immutable objects.
|
7
7
|
#
|
8
|
-
# NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
|
8
|
+
# NOTE: `Regexp` and `Range` literals are frozen objects since Ruby 3.0.
|
9
9
|
#
|
10
10
|
# NOTE: From Ruby 3.0, this cop allows explicit freezing of interpolated
|
11
11
|
# string literals when `# frozen-string-literal: true` is used.
|
@@ -73,10 +73,15 @@ module RuboCop
|
|
73
73
|
LINE_CONTINUATION_PATTERN = /(\\\n)/.freeze
|
74
74
|
ALLOWED_STRING_TOKENS = %i[tSTRING tSTRING_CONTENT].freeze
|
75
75
|
ARGUMENT_TYPES = %i[
|
76
|
-
kDEF kFALSE kNIL kSELF kTRUE
|
77
|
-
|
76
|
+
kDEF kDEFINED kFALSE kNIL kSELF kTRUE tAMPER tBANG tCARET tCHARACTER tCOLON3 tCONSTANT
|
77
|
+
tCVAR tDOT2 tDOT3 tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR tLAMBDA tLBRACK tLCURLY
|
78
|
+
tLPAREN_ARG tPIPE tQSYMBOLS_BEG tQWORDS_BEG tREGEXP_BEG tSTAR tSTRING tSTRING_BEG tSYMBEG
|
79
|
+
tSYMBOL tSYMBOLS_BEG tTILDE tUMINUS tUNARY_NUM tUPLUS tWORDS_BEG tXSTRING_BEG
|
78
80
|
].freeze
|
79
|
-
ARGUMENT_TAKING_FLOW_TOKEN_TYPES = %i[
|
81
|
+
ARGUMENT_TAKING_FLOW_TOKEN_TYPES = %i[
|
82
|
+
tIDENTIFIER kBREAK kNEXT kRETURN kSUPER kYIELD
|
83
|
+
].freeze
|
84
|
+
ARITHMETIC_OPERATOR_TOKENS = %i[tDIVIDE tDSTAR tMINUS tPERCENT tPLUS tSTAR2].freeze
|
80
85
|
|
81
86
|
def on_new_investigation
|
82
87
|
return unless processed_source.ast
|
@@ -96,15 +101,20 @@ module RuboCop
|
|
96
101
|
private
|
97
102
|
|
98
103
|
def require_line_continuation?(range)
|
99
|
-
!
|
104
|
+
!ends_with_uncommented_backslash?(range) ||
|
100
105
|
string_concatenation?(range.source_line) ||
|
101
|
-
start_with_arithmetic_operator?(
|
106
|
+
start_with_arithmetic_operator?(range) ||
|
102
107
|
inside_string_literal_or_method_with_argument?(range) ||
|
103
108
|
leading_dot_method_chain_with_blank_line?(range)
|
104
109
|
end
|
105
110
|
|
106
|
-
def
|
107
|
-
|
111
|
+
def ends_with_uncommented_backslash?(range)
|
112
|
+
# A line continuation always needs to be the last character on the line, which
|
113
|
+
# means that it is impossible to have a comment following a continuation.
|
114
|
+
# Therefore, if the line contains a comment, it cannot end with a continuation.
|
115
|
+
return false if processed_source.line_with_comment?(range.line)
|
116
|
+
|
117
|
+
range.source_line.end_with?(LINE_CONTINUATION)
|
108
118
|
end
|
109
119
|
|
110
120
|
def string_concatenation?(source_line)
|
@@ -140,7 +150,7 @@ module RuboCop
|
|
140
150
|
|
141
151
|
def inspect_end_of_ruby_code_line_continuation
|
142
152
|
last_line = processed_source.lines[processed_source.ast.last_line - 1]
|
143
|
-
return unless
|
153
|
+
return unless code_ends_with_continuation?(last_line)
|
144
154
|
|
145
155
|
last_column = last_line.length
|
146
156
|
line_continuation_range = range_between(last_column - 1, last_column)
|
@@ -150,6 +160,12 @@ module RuboCop
|
|
150
160
|
end
|
151
161
|
end
|
152
162
|
|
163
|
+
def code_ends_with_continuation?(last_line)
|
164
|
+
return false if processed_source.line_with_comment?(processed_source.ast.last_line)
|
165
|
+
|
166
|
+
last_line.end_with?(LINE_CONTINUATION)
|
167
|
+
end
|
168
|
+
|
153
169
|
def inside_string_literal?(range, token)
|
154
170
|
ALLOWED_STRING_TOKENS.include?(token.type) && token.pos.overlaps?(range)
|
155
171
|
end
|
@@ -213,8 +229,9 @@ module RuboCop
|
|
213
229
|
node.call_type? && !node.arguments.empty?
|
214
230
|
end
|
215
231
|
|
216
|
-
def start_with_arithmetic_operator?(
|
217
|
-
|
232
|
+
def start_with_arithmetic_operator?(range)
|
233
|
+
line_range = processed_source.buffer.line_range(range.line + 1)
|
234
|
+
ARITHMETIC_OPERATOR_TOKENS.include?(processed_source.first_token_of(line_range).type)
|
218
235
|
end
|
219
236
|
end
|
220
237
|
end
|
@@ -140,6 +140,9 @@ module RuboCop
|
|
140
140
|
return 'a literal' if disallowed_literal?(begin_node, node)
|
141
141
|
return 'a variable' if node.variable?
|
142
142
|
return 'a constant' if node.const_type?
|
143
|
+
if node.assignment? && (begin_node.parent.nil? || begin_node.parent.begin_type?)
|
144
|
+
return 'an assignment'
|
145
|
+
end
|
143
146
|
if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
|
144
147
|
return 'an expression'
|
145
148
|
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# parameters.
|
11
11
|
#
|
12
12
|
# Configuration option: Methods
|
13
|
-
# Should be set to use this cop. Array of hashes, where each key is the
|
13
|
+
# Should be set to use this cop. `Array` of hashes, where each key is the
|
14
14
|
# method name and value - array of argument names.
|
15
15
|
#
|
16
16
|
# @example Methods: [{reduce: %w[a b]}]
|
@@ -243,7 +243,7 @@ module RuboCop
|
|
243
243
|
def replace_condition(condition)
|
244
244
|
return condition.source unless wrap_condition?(condition)
|
245
245
|
|
246
|
-
if condition.call_type?
|
246
|
+
if condition.call_type? && !condition.comparison_method?
|
247
247
|
parenthesized_method_arguments(condition)
|
248
248
|
else
|
249
249
|
"(#{condition.source})"
|
@@ -7,12 +7,15 @@ module RuboCop
|
|
7
7
|
# The supported styles are:
|
8
8
|
#
|
9
9
|
# * `consistent_comma`: Requires a comma after the last argument,
|
10
|
-
# for all parenthesized method calls with arguments.
|
10
|
+
# for all parenthesized multi-line method calls with arguments.
|
11
11
|
# * `comma`: Requires a comma after the last argument, but only for
|
12
12
|
# parenthesized method calls where each argument is on its own line.
|
13
13
|
# * `no_comma`: Requires that there is no comma after the last
|
14
14
|
# argument.
|
15
15
|
#
|
16
|
+
# Regardless of style, trailing commas are not allowed in
|
17
|
+
# single-line method calls.
|
18
|
+
#
|
16
19
|
# @example EnforcedStyleForMultiline: consistent_comma
|
17
20
|
# # bad
|
18
21
|
# method(1, 2,)
|
@@ -18,7 +18,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
18
18
|
description: ->(data) { "#{data.description}\n" },
|
19
19
|
safety: ->(data) { safety_object(data.safety_objects, data.cop) },
|
20
20
|
examples: ->(data) { examples(data.example_objects, data.cop) },
|
21
|
-
configuration: ->(data) { configurations(data.cop.department, data.
|
21
|
+
configuration: ->(data) { configurations(data.cop.department, data.cop, data.config) },
|
22
22
|
references: ->(data) { references(data.cop, data.see_objects) }
|
23
23
|
}.freeze
|
24
24
|
|
@@ -180,17 +180,17 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
180
180
|
content
|
181
181
|
end
|
182
182
|
|
183
|
-
def configurations(department,
|
184
|
-
return '' if pars.empty?
|
185
|
-
|
183
|
+
def configurations(department, cop, cop_config)
|
186
184
|
header = ['Name', 'Default value', 'Configurable values']
|
187
|
-
configs =
|
185
|
+
configs = cop_config
|
188
186
|
.each_key
|
189
187
|
.reject { |key| key.start_with?('Supported') }
|
190
188
|
.reject { |key| key.start_with?('AllowMultipleStyles') }
|
189
|
+
return '' if configs.empty?
|
190
|
+
|
191
191
|
content = configs.map do |name|
|
192
|
-
configurable = configurable_values(
|
193
|
-
default = format_table_value(
|
192
|
+
configurable = configurable_values(cop_config, name)
|
193
|
+
default = format_table_value(cop_config[name])
|
194
194
|
|
195
195
|
[configuration_name(department, name), default, configurable]
|
196
196
|
end
|
@@ -206,17 +206,17 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
206
206
|
end
|
207
207
|
|
208
208
|
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
|
209
|
-
def configurable_values(
|
209
|
+
def configurable_values(cop_config, name)
|
210
210
|
case name
|
211
211
|
when /^Enforced/
|
212
212
|
supported_style_name = RuboCop::Cop::Util.to_supported_styles(name)
|
213
|
-
format_table_value(
|
213
|
+
format_table_value(cop_config[supported_style_name])
|
214
214
|
when 'IndentationWidth'
|
215
215
|
'Integer'
|
216
216
|
when 'Database'
|
217
|
-
format_table_value(
|
217
|
+
format_table_value(cop_config['SupportedDatabases'])
|
218
218
|
else
|
219
|
-
case
|
219
|
+
case cop_config[name]
|
220
220
|
when String
|
221
221
|
'String'
|
222
222
|
when Integer
|
@@ -319,7 +319,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
319
319
|
AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
|
320
320
|
VersionChanged
|
321
321
|
]
|
322
|
-
|
322
|
+
parameters = cop_config.reject { |k| non_display_keys.include? k }
|
323
323
|
description = 'No documentation'
|
324
324
|
example_objects = safety_objects = see_objects = []
|
325
325
|
cop_code(cop) do |code_object|
|
@@ -329,7 +329,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
329
329
|
see_objects = code_object.tags('see')
|
330
330
|
end
|
331
331
|
data = CopData.new(cop: cop, description: description, example_objects: example_objects,
|
332
|
-
safety_objects: safety_objects, see_objects: see_objects, config:
|
332
|
+
safety_objects: safety_objects, see_objects: see_objects, config: parameters)
|
333
333
|
cops_body(data)
|
334
334
|
end
|
335
335
|
|
@@ -88,10 +88,15 @@ module RuboCop
|
|
88
88
|
@cop_names ||= all_cops? ? all_cop_names : parsed_cop_names
|
89
89
|
end
|
90
90
|
|
91
|
+
# Returns an array of cops for this directive comment, without resolving departments
|
92
|
+
def raw_cop_names
|
93
|
+
@raw_cop_names ||= (cops || '').split(/,\s*/)
|
94
|
+
end
|
95
|
+
|
91
96
|
# Returns array of specified in this directive department names
|
92
97
|
# when all department disabled
|
93
98
|
def department_names
|
94
|
-
|
99
|
+
raw_cop_names.select { |cop| department?(cop) }
|
95
100
|
end
|
96
101
|
|
97
102
|
# Checks if directive departments include cop
|
@@ -101,11 +106,11 @@ module RuboCop
|
|
101
106
|
|
102
107
|
# Checks if cop department has already used in directive comment
|
103
108
|
def overridden_by_department?(cop)
|
104
|
-
in_directive_department?(cop) &&
|
109
|
+
in_directive_department?(cop) && raw_cop_names.include?(cop)
|
105
110
|
end
|
106
111
|
|
107
112
|
def directive_count
|
108
|
-
|
113
|
+
raw_cop_names.count
|
109
114
|
end
|
110
115
|
|
111
116
|
# Returns line number for directive
|
@@ -115,12 +120,8 @@ module RuboCop
|
|
115
120
|
|
116
121
|
private
|
117
122
|
|
118
|
-
def splitted_cops_string
|
119
|
-
(cops || '').split(/,\s*/)
|
120
|
-
end
|
121
|
-
|
122
123
|
def parsed_cop_names
|
123
|
-
cops =
|
124
|
+
cops = raw_cop_names.map do |name|
|
124
125
|
department?(name) ? cop_names_for_department(name) : name
|
125
126
|
end.flatten
|
126
127
|
cops - [LINT_SYNTAX_COP]
|
data/lib/rubocop/options.rb
CHANGED
@@ -579,7 +579,8 @@ module RuboCop
|
|
579
579
|
'when combined with --display-only-correctable.'],
|
580
580
|
show_cops: ['Shows the given cops, or all cops by',
|
581
581
|
'default, and their configurations for the',
|
582
|
-
'current directory.'
|
582
|
+
'current directory.',
|
583
|
+
'You can use `*` as a wildcard.'],
|
583
584
|
show_docs_url: ['Display url to documentation for the given',
|
584
585
|
'cops, or base url by default.'],
|
585
586
|
fail_fast: ['Inspect files in order of modification',
|