rubocop 1.68.0 → 1.69.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 +41 -6
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +2 -4
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +46 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -4
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +15 -0
- data/lib/rubocop/cop/layout/line_length.rb +118 -4
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -35
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +16 -17
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +11 -12
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +14 -6
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -3
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -5
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +106 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -0
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +3 -2
- data/lib/rubocop/cop/metrics/class_length.rb +7 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
- data/lib/rubocop/cop/mixin/range_help.rb +0 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -11
- data/lib/rubocop/cop/naming/variable_name.rb +3 -4
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +53 -24
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/array_intersect.rb +5 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +19 -21
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/dig_chain.rb +90 -0
- data/lib/rubocop/cop/style/file_null.rb +73 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/for.rb +0 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +1 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +14 -5
- data/lib/rubocop/cop/style/inverse_methods.rb +0 -1
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +2 -2
- data/lib/rubocop/cop/style/lambda_call.rb +0 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +7 -11
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -4
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +8 -13
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +36 -21
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +7 -6
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -0
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +7 -14
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +7 -5
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +13 -3
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -3
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +0 -1
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/variable_force.rb +4 -10
- data/lib/rubocop/cops_documentation_generator.rb +9 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +8 -0
- metadata +17 -8
@@ -12,7 +12,7 @@ module RuboCop
|
|
12
12
|
# first parameter of the definition, then the closing brace should be
|
13
13
|
# on the same line as the last parameter of the definition.
|
14
14
|
#
|
15
|
-
# If
|
15
|
+
# If a method definition's opening brace is on the line above the first
|
16
16
|
# parameter of the definition, then the closing brace should be on the
|
17
17
|
# line below the last parameter of the definition.
|
18
18
|
#
|
@@ -76,9 +76,8 @@ module RuboCop
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def check_and_or(node)
|
79
|
-
lhs, rhs
|
80
|
-
range
|
81
|
-
check(range, node, lhs, rhs.source_range)
|
79
|
+
range = offending_range(node, node.lhs, node.rhs.source_range, style)
|
80
|
+
check(range, node, node.lhs, node.rhs.source_range)
|
82
81
|
end
|
83
82
|
|
84
83
|
def offending_range(node, lhs, rhs, given_style)
|
@@ -3,11 +3,10 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Layout
|
6
|
-
#
|
7
|
-
# definition are aligned.
|
6
|
+
# Check that the parameters on a multi-line method call or definition are aligned.
|
8
7
|
#
|
9
|
-
# To set the alignment of the first argument, use the
|
10
|
-
# FirstParameterIndentation.
|
8
|
+
# To set the alignment of the first argument, use the
|
9
|
+
# `Layout/FirstParameterIndentation` cop.
|
11
10
|
#
|
12
11
|
# @example EnforcedStyle: with_first_parameter (default)
|
13
12
|
# # good
|
@@ -44,6 +44,7 @@ module RuboCop
|
|
44
44
|
#
|
45
45
|
class RedundantLineBreak < Base
|
46
46
|
include CheckAssignment
|
47
|
+
include CheckSingleLineSuitability
|
47
48
|
extend AutoCorrector
|
48
49
|
|
49
50
|
MSG = 'Redundant line break detected.'
|
@@ -84,8 +85,8 @@ module RuboCop
|
|
84
85
|
end
|
85
86
|
|
86
87
|
def offense?(node)
|
87
|
-
return false
|
88
|
-
return require_backslash?(node) if node.
|
88
|
+
return false unless node.multiline? && suitable_as_single_line?(node)
|
89
|
+
return require_backslash?(node) if node.operator_keyword?
|
89
90
|
|
90
91
|
!index_access_call_chained?(node) && !configured_to_not_be_inspected?(node)
|
91
92
|
end
|
@@ -117,44 +118,11 @@ module RuboCop
|
|
117
118
|
@config.for_cop('Layout/SingleLineBlockChain')['Enabled']
|
118
119
|
end
|
119
120
|
|
120
|
-
def suitable_as_single_line?(node)
|
121
|
-
!comment_within?(node) &&
|
122
|
-
node.each_descendant(:if, :case, :kwbegin, :def, :defs).none? &&
|
123
|
-
node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
|
124
|
-
node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
|
125
|
-
end
|
126
|
-
|
127
121
|
def convertible_block?(node)
|
128
122
|
parent = node.parent
|
129
123
|
parent&.block_type? && node == parent.send_node &&
|
130
124
|
(node.parenthesized? || !node.arguments?)
|
131
125
|
end
|
132
|
-
|
133
|
-
def comment_within?(node)
|
134
|
-
comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
|
135
|
-
|
136
|
-
comment_line_numbers.any? do |comment_line_number|
|
137
|
-
comment_line_number >= node.first_line && comment_line_number <= node.last_line
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def too_long?(node)
|
142
|
-
lines = processed_source.lines[(node.first_line - 1)...node.last_line]
|
143
|
-
to_single_line(lines.join("\n")).length > max_line_length
|
144
|
-
end
|
145
|
-
|
146
|
-
def to_single_line(source)
|
147
|
-
source
|
148
|
-
.gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
|
149
|
-
.gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
|
150
|
-
.gsub(/(["']) *\\\n\s*\1/, '') # Double or single quote, backslash, then same quote
|
151
|
-
.gsub(/\n\s*(?=(&)?\.\w)/, '') # Extra space within method chaining which includes `&.`
|
152
|
-
.gsub(/\s*\\?\n\s*/, ' ') # Any other line break, with or without backslash
|
153
|
-
end
|
154
|
-
|
155
|
-
def max_line_length
|
156
|
-
config.for_cop('Layout/LineLength')['Max']
|
157
|
-
end
|
158
126
|
end
|
159
127
|
end
|
160
128
|
end
|
@@ -92,6 +92,7 @@ module RuboCop
|
|
92
92
|
)
|
93
93
|
end
|
94
94
|
|
95
|
+
# rubocop:disable Metrics/AbcSize
|
95
96
|
def alignment_source(node, starting_loc)
|
96
97
|
ending_loc =
|
97
98
|
case node.type
|
@@ -101,8 +102,7 @@ module RuboCop
|
|
101
102
|
:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
|
102
103
|
node.loc.name
|
103
104
|
when :masgn
|
104
|
-
|
105
|
-
mlhs_node.source_range
|
105
|
+
node.lhs.source_range
|
106
106
|
else
|
107
107
|
# It is a wrapper with receiver of object attribute or access modifier.
|
108
108
|
node.receiver&.source_range || node.child_nodes.first.loc.name
|
@@ -110,6 +110,7 @@ module RuboCop
|
|
110
110
|
|
111
111
|
range_between(starting_loc.begin_pos, ending_loc.end_pos).source
|
112
112
|
end
|
113
|
+
# rubocop:enable Metrics/AbcSize
|
113
114
|
|
114
115
|
# We will use ancestor or wrapper with access modifier.
|
115
116
|
|
@@ -256,7 +256,7 @@ module RuboCop
|
|
256
256
|
# regular dotted method calls bind more tightly than operators
|
257
257
|
# so we need to climb up the AST past them
|
258
258
|
node.each_ancestor do |ancestor|
|
259
|
-
return true if ancestor.
|
259
|
+
return true if ancestor.operator_keyword? || ancestor.range_type?
|
260
260
|
return false unless ancestor.send_type?
|
261
261
|
return true if ancestor.operator_method?
|
262
262
|
end
|
@@ -99,51 +99,50 @@ module RuboCop
|
|
99
99
|
def on_resbody(node)
|
100
100
|
return unless node.loc.assoc
|
101
101
|
|
102
|
-
|
103
|
-
|
104
|
-
check_operator(:resbody, node.loc.assoc, variable)
|
102
|
+
check_operator(:resbody, node.loc.assoc, node.exception_variable)
|
105
103
|
end
|
106
104
|
|
107
105
|
def on_send(node)
|
108
106
|
return if rational_literal?(node)
|
109
107
|
|
110
108
|
if node.setter_method?
|
111
|
-
|
109
|
+
on_setter_method(node)
|
112
110
|
elsif regular_operator?(node)
|
113
111
|
check_operator(:send, node.loc.selector, node.first_argument)
|
114
112
|
end
|
115
113
|
end
|
116
114
|
|
117
115
|
def on_assignment(node)
|
118
|
-
|
116
|
+
rhs = node.rhs
|
119
117
|
|
120
118
|
return unless rhs
|
121
119
|
|
122
|
-
|
120
|
+
type = node.op_asgn_type? ? :special_asgn : :assignment
|
121
|
+
check_operator(type, node.loc.operator, rhs)
|
123
122
|
end
|
124
123
|
|
125
|
-
def
|
126
|
-
|
124
|
+
def on_class(node)
|
125
|
+
rhs = node.parent_class
|
127
126
|
|
128
|
-
return unless
|
127
|
+
return unless rhs
|
129
128
|
|
130
|
-
check_operator(:
|
129
|
+
check_operator(:class, node.loc.operator, rhs)
|
131
130
|
end
|
132
131
|
|
133
132
|
def on_binary(node)
|
134
|
-
|
133
|
+
rhs = node.rhs
|
135
134
|
|
136
135
|
return unless rhs
|
137
136
|
|
138
137
|
check_operator(:binary, node.loc.operator, rhs)
|
139
138
|
end
|
140
139
|
|
141
|
-
def
|
142
|
-
|
140
|
+
def on_setter_method(node)
|
141
|
+
rhs = node.first_argument
|
143
142
|
|
144
|
-
return unless
|
143
|
+
return unless rhs
|
145
144
|
|
146
|
-
check_operator(:special_asgn, node.loc.operator,
|
145
|
+
check_operator(:special_asgn, node.loc.operator, node.first_argument)
|
147
146
|
end
|
148
147
|
|
149
148
|
def on_match_pattern(node)
|
@@ -155,14 +154,14 @@ module RuboCop
|
|
155
154
|
alias on_or on_binary
|
156
155
|
alias on_and on_binary
|
157
156
|
alias on_lvasgn on_assignment
|
157
|
+
alias on_casgn on_assignment
|
158
158
|
alias on_masgn on_assignment
|
159
159
|
alias on_ivasgn on_assignment
|
160
160
|
alias on_cvasgn on_assignment
|
161
161
|
alias on_gvasgn on_assignment
|
162
|
-
alias on_class on_binary
|
163
162
|
alias on_or_asgn on_assignment
|
164
163
|
alias on_and_asgn on_assignment
|
165
|
-
alias on_op_asgn
|
164
|
+
alias on_op_asgn on_assignment
|
166
165
|
|
167
166
|
private
|
168
167
|
|
@@ -12,9 +12,11 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# # bad
|
14
14
|
# array = [ a, b, c, d ]
|
15
|
+
# array = [ a, [ b, c ]]
|
15
16
|
#
|
16
17
|
# # good
|
17
18
|
# array = [a, b, c, d]
|
19
|
+
# array = [a, [b, c]]
|
18
20
|
#
|
19
21
|
# @example EnforcedStyle: space
|
20
22
|
# # The `space` style enforces that array literals have
|
@@ -22,9 +24,11 @@ module RuboCop
|
|
22
24
|
#
|
23
25
|
# # bad
|
24
26
|
# array = [a, b, c, d]
|
27
|
+
# array = [ a, [ b, c ]]
|
25
28
|
#
|
26
29
|
# # good
|
27
30
|
# array = [ a, b, c, d ]
|
31
|
+
# array = [ a, [ b, c ] ]
|
28
32
|
#
|
29
33
|
# @example EnforcedStyle: compact
|
30
34
|
# # The `compact` style normally requires a space inside
|
@@ -32,6 +36,7 @@ module RuboCop
|
|
32
36
|
# # or right brackets are collapsed together in nested arrays.
|
33
37
|
#
|
34
38
|
# # bad
|
39
|
+
# array = [a, b, c, d]
|
35
40
|
# array = [ a, [ b, c ] ]
|
36
41
|
# array = [
|
37
42
|
# [ a ],
|
@@ -39,6 +44,7 @@ module RuboCop
|
|
39
44
|
# ]
|
40
45
|
#
|
41
46
|
# # good
|
47
|
+
# array = [ a, b, c, d ]
|
42
48
|
# array = [ a, [ b, c ]]
|
43
49
|
# array = [[ a ],
|
44
50
|
# [ b, c ]]
|
@@ -12,9 +12,11 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# # bad
|
14
14
|
# h = {a: 1, b: 2}
|
15
|
+
# foo = {{ a: 1 } => { b: { c: 2 }}}
|
15
16
|
#
|
16
17
|
# # good
|
17
18
|
# h = { a: 1, b: 2 }
|
19
|
+
# foo = { { a: 1 } => { b: { c: 2 } } }
|
18
20
|
#
|
19
21
|
# @example EnforcedStyle: no_space
|
20
22
|
# # The `no_space` style enforces that hash literals have
|
@@ -22,9 +24,11 @@ module RuboCop
|
|
22
24
|
#
|
23
25
|
# # bad
|
24
26
|
# h = { a: 1, b: 2 }
|
27
|
+
# foo = {{ a: 1 } => { b: { c: 2 }}}
|
25
28
|
#
|
26
29
|
# # good
|
27
30
|
# h = {a: 1, b: 2}
|
31
|
+
# foo = {{a: 1} => {b: {c: 2}}}
|
28
32
|
#
|
29
33
|
# @example EnforcedStyle: compact
|
30
34
|
# # The `compact` style normally requires a space inside
|
@@ -5,17 +5,16 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# Checks for places where binary operator has identical operands.
|
7
7
|
#
|
8
|
-
# It covers
|
9
|
-
# comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
|
8
|
+
# It covers comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
|
10
9
|
# bitwise operators: `|`, `^`, `&`;
|
11
10
|
# boolean operators: `&&`, `||`
|
12
11
|
# and "spaceship" operator - ``<=>``.
|
13
12
|
#
|
14
13
|
# Simple arithmetic operations are allowed by this cop: `+`, `*`, `**`, `<<` and `>>`.
|
15
14
|
# Although these can be rewritten in a different way, it should not be necessary to
|
16
|
-
# do so.
|
17
|
-
#
|
18
|
-
#
|
15
|
+
# do so. Operations such as `-` or `/` where the result will always be the same
|
16
|
+
# (`x - x` will always be 0; `x / x` will always be 1) are offenses, but these
|
17
|
+
# are covered by Lint/NumericOperationWithConstantResult instead.
|
19
18
|
#
|
20
19
|
# @safety
|
21
20
|
# This cop is unsafe as it does not consider side effects when calling methods
|
@@ -30,7 +29,6 @@ module RuboCop
|
|
30
29
|
#
|
31
30
|
# @example
|
32
31
|
# # bad
|
33
|
-
# x / x
|
34
32
|
# x.top >= x.top
|
35
33
|
#
|
36
34
|
# if a.x != 0 && a.x != 0
|
@@ -47,19 +45,20 @@ module RuboCop
|
|
47
45
|
#
|
48
46
|
class BinaryOperatorWithIdenticalOperands < Base
|
49
47
|
MSG = 'Binary operator `%<op>s` has identical operands.'
|
50
|
-
|
48
|
+
MATH_OPERATORS = %i[- + * / ** << >>].to_set.freeze
|
51
49
|
|
52
50
|
def on_send(node)
|
53
51
|
return unless node.binary_operation?
|
52
|
+
return if MATH_OPERATORS.include?(node.method_name)
|
53
|
+
return unless node.receiver == node.first_argument
|
54
54
|
|
55
|
-
|
56
|
-
return if ALLOWED_MATH_OPERATORS.include?(node.method_name)
|
57
|
-
|
58
|
-
add_offense(node, message: format(MSG, op: operation)) if lhs == rhs
|
55
|
+
add_offense(node, message: format(MSG, op: node.method_name))
|
59
56
|
end
|
60
57
|
|
61
58
|
def on_and(node)
|
62
|
-
|
59
|
+
return unless node.lhs == node.rhs
|
60
|
+
|
61
|
+
add_offense(node, message: format(MSG, op: node.operator))
|
63
62
|
end
|
64
63
|
alias on_or on_and
|
65
64
|
end
|
@@ -51,7 +51,7 @@ module RuboCop
|
|
51
51
|
PATTERN
|
52
52
|
|
53
53
|
def on_send(node)
|
54
|
-
return if node.arguments.any? { |arg| arg.variable? || arg.
|
54
|
+
return if node.arguments.any? { |arg| arg.variable? || arg.call_type? || arg.const_type? }
|
55
55
|
return if digest_const?(node.receiver)
|
56
56
|
return unless algorithm_const(node)
|
57
57
|
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
43
43
|
MSG = 'Do not return from an `ensure` block.'
|
44
44
|
|
45
45
|
def on_ensure(node)
|
46
|
-
node.
|
46
|
+
node.branch&.each_node(:return) { |return_node| add_offense(return_node) }
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -29,6 +29,9 @@ module RuboCop
|
|
29
29
|
# tolerance = 0.0001
|
30
30
|
# (x - 0.1).abs < tolerance
|
31
31
|
#
|
32
|
+
# # good - comparing against nil
|
33
|
+
# Float(x, exception: false) == nil
|
34
|
+
#
|
32
35
|
# # Or some other epsilon based type of comparison:
|
33
36
|
# # https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
|
34
37
|
#
|
@@ -42,8 +45,12 @@ module RuboCop
|
|
42
45
|
RESTRICT_ON_SEND = EQUALITY_METHODS
|
43
46
|
|
44
47
|
def on_send(node)
|
45
|
-
|
46
|
-
|
48
|
+
return unless node.arguments.one?
|
49
|
+
|
50
|
+
lhs = node.receiver
|
51
|
+
rhs = node.first_argument
|
52
|
+
|
53
|
+
return if literal_safe?(lhs) || literal_safe?(rhs)
|
47
54
|
|
48
55
|
add_offense(node) if float?(lhs) || float?(rhs)
|
49
56
|
end
|
@@ -65,15 +72,16 @@ module RuboCop
|
|
65
72
|
end
|
66
73
|
end
|
67
74
|
|
68
|
-
def
|
69
|
-
|
75
|
+
def literal_safe?(node)
|
76
|
+
return false unless node
|
77
|
+
|
78
|
+
(node.numeric_type? && node.value.zero?) || node.nil_type?
|
70
79
|
end
|
71
80
|
|
72
81
|
# rubocop:disable Metrics/PerceivedComplexity
|
73
82
|
def check_send(node)
|
74
83
|
if node.arithmetic_operation?
|
75
|
-
|
76
|
-
float?(lhs) || float?(rhs)
|
84
|
+
float?(node.receiver) || float?(node.first_argument)
|
77
85
|
elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
|
78
86
|
true
|
79
87
|
elsif node.receiver&.float_type?
|
@@ -18,9 +18,7 @@ module RuboCop
|
|
18
18
|
MSG = 'Float out of range.'
|
19
19
|
|
20
20
|
def on_float(node)
|
21
|
-
value
|
22
|
-
|
23
|
-
return unless value.infinite? || (value.zero? && /[1-9]/.match?(node.source))
|
21
|
+
return unless node.value.infinite? || (node.value.zero? && /[1-9]/.match?(node.source))
|
24
22
|
|
25
23
|
add_offense(node)
|
26
24
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for the deprecated use of keyword arguments as a default in `Hash.new`.
|
7
|
+
#
|
8
|
+
# This usage raises a warning in Ruby 3.3 and results in an error in Ruby 3.4.
|
9
|
+
# In Ruby 3.4, keyword arguments will instead be used to change the behavior of a hash.
|
10
|
+
# For example, the capacity option can be passed to create a hash with a certain size
|
11
|
+
# if you know it in advance, for better performance.
|
12
|
+
#
|
13
|
+
# NOTE: The following corner case may result in a false negative when upgrading from Ruby 3.3
|
14
|
+
# or earlier, but it is intentionally not detected to respect the expected usage in Ruby 3.4.
|
15
|
+
#
|
16
|
+
# [source,ruby]
|
17
|
+
# ----
|
18
|
+
# Hash.new(capacity: 42)
|
19
|
+
# ----
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# Hash.new(key: :value)
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# Hash.new({key: :value})
|
28
|
+
#
|
29
|
+
class HashNewWithKeywordArgumentsAsDefault < Base
|
30
|
+
extend AutoCorrector
|
31
|
+
|
32
|
+
MSG = 'Use a hash literal instead of keyword arguments.'
|
33
|
+
RESTRICT_ON_SEND = %i[new].freeze
|
34
|
+
|
35
|
+
# @!method hash_new(node)
|
36
|
+
def_node_matcher :hash_new, <<~PATTERN
|
37
|
+
(send (const {nil? (cbase)} :Hash) :new $[hash !braces?])
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def on_send(node)
|
41
|
+
return unless (first_argument = hash_new(node))
|
42
|
+
|
43
|
+
if first_argument.pairs.one?
|
44
|
+
key = first_argument.pairs.first.key
|
45
|
+
return if key.respond_to?(:value) && key.value == :capacity
|
46
|
+
end
|
47
|
+
|
48
|
+
add_offense(first_argument) do |corrector|
|
49
|
+
corrector.wrap(first_argument, '{', '}')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -24,14 +24,17 @@ module RuboCop
|
|
24
24
|
MSG = 'Interpolation in single quoted string detected. ' \
|
25
25
|
'Use double quoted strings if you need interpolation.'
|
26
26
|
|
27
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
27
28
|
def on_str(node)
|
28
29
|
return if node.parent&.regexp_type?
|
29
30
|
return unless /(?<!\\)#\{.*\}/.match?(node.source)
|
30
31
|
return if heredoc?(node)
|
31
32
|
return unless node.loc.begin && node.loc.end
|
33
|
+
return unless valid_syntax?(node)
|
32
34
|
|
33
35
|
add_offense(node) { |corrector| autocorrect(corrector, node) }
|
34
36
|
end
|
37
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
35
38
|
|
36
39
|
private
|
37
40
|
|
@@ -49,6 +52,12 @@ module RuboCop
|
|
49
52
|
def heredoc?(node)
|
50
53
|
node.loc.is_a?(Parser::Source::Map::Heredoc) || (node.parent && heredoc?(node.parent))
|
51
54
|
end
|
55
|
+
|
56
|
+
def valid_syntax?(node)
|
57
|
+
double_quoted_string = node.source.gsub(/\A'|'\z/, '"')
|
58
|
+
|
59
|
+
parse(double_quoted_string).valid_syntax?
|
60
|
+
end
|
52
61
|
end
|
53
62
|
end
|
54
63
|
end
|
@@ -26,6 +26,9 @@ module RuboCop
|
|
26
26
|
#
|
27
27
|
class ItWithoutArgumentsInBlock < Base
|
28
28
|
include NodePattern::Macros
|
29
|
+
extend TargetRubyVersion
|
30
|
+
|
31
|
+
maximum_target_ruby_version 3.3
|
29
32
|
|
30
33
|
MSG = '`it` calls without arguments will refer to the first block param in Ruby 3.4; ' \
|
31
34
|
'use `it()` or `self.it`.'
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
traverse_node(node.condition) do |asgn_node|
|
41
41
|
next unless asgn_node.loc.operator
|
42
42
|
|
43
|
-
rhs = asgn_node.
|
43
|
+
rhs = asgn_node.rhs
|
44
44
|
next if !all_literals?(rhs) || parallel_assignment_with_splat_operator?(rhs)
|
45
45
|
|
46
46
|
range = offense_range(asgn_node, rhs)
|
@@ -36,12 +36,9 @@ module RuboCop
|
|
36
36
|
|
37
37
|
def on_irange(node)
|
38
38
|
return unless node.children.compact.all?(&:str_type?)
|
39
|
+
return if node.begin.nil? || node.end.nil?
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
return if range_start.nil? || range_end.nil?
|
43
|
-
|
44
|
-
add_offense(node) if unsafe_range?(range_start.value, range_end.value)
|
41
|
+
add_offense(node) if unsafe_range?(node.begin.value, node.end.value)
|
45
42
|
end
|
46
43
|
alias on_erange on_irange
|
47
44
|
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
95
95
|
MSG = 'Method definitions must not be nested. Use `lambda` instead.'
|
96
96
|
|
97
97
|
def on_def(node)
|
98
|
-
subject, = *node
|
98
|
+
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
99
99
|
return if node.defs_type? && subject.variable?
|
100
100
|
|
101
101
|
def_ancestor = node.each_ancestor(:def, :defs).first
|
@@ -95,7 +95,7 @@ module RuboCop
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def allowable_use_with_if?(if_node)
|
98
|
-
if_node.condition.
|
98
|
+
if_node.condition.operator_keyword? || if_node.else_branch
|
99
99
|
end
|
100
100
|
|
101
101
|
def register_offense(node, exist_node)
|
@@ -33,8 +33,7 @@ module RuboCop
|
|
33
33
|
NUMBERED_PARAMETER_RANGE = (1..9).freeze
|
34
34
|
|
35
35
|
def on_lvasgn(node)
|
36
|
-
|
37
|
-
return unless /\A_(\d+)\z/ =~ lhs
|
36
|
+
return unless /\A_(\d+)\z/ =~ node.name
|
38
37
|
|
39
38
|
number = Regexp.last_match(1).to_i
|
40
39
|
template = NUMBERED_PARAMETER_RANGE.include?(number) ? NUM_PARAM_MSG : LVAR_MSG
|