rubocop 1.73.1 → 1.75.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/README.md +1 -1
- data/config/default.yml +64 -10
- data/config/internal_affairs.yml +4 -0
- data/config/obsoletion.yml +3 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +35 -6
- data/lib/rubocop/config_loader.rb +4 -1
- data/lib/rubocop/config_loader_resolver.rb +2 -1
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/line_length.rb +5 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +9 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/lint/debugger.rb +2 -2
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +15 -70
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/literal_as_condition.rb +4 -0
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +9 -3
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/return_in_void_context.rb +4 -11
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +12 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -0
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +2 -11
- data/lib/rubocop/cop/lint/void.rb +1 -0
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/method_length.rb +1 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
- data/lib/rubocop/cop/mixin/range_help.rb +12 -0
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +64 -8
- data/lib/rubocop/cop/naming/variable_name.rb +6 -19
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/style/array_intersect.rb +39 -28
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/class_and_module_children.rb +29 -7
- data/lib/rubocop/cop/style/collection_methods.rb +1 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +1 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +9 -2
- data/lib/rubocop/cop/style/comparable_between.rb +75 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/exponential_notation.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -2
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +105 -0
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -5
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +13 -7
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/map_into_array.rb +1 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -3
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/proc.rb +1 -0
- data/lib/rubocop/cop/style/raise_args.rb +8 -8
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -3
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +14 -4
- data/lib/rubocop/cop/style/redundant_format.rb +10 -3
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/redundant_self.rb +1 -0
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +41 -106
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -0
- data/lib/rubocop/cop/utils/format_string.rb +5 -2
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +1 -6
- data/lib/rubocop/cop/variable_force.rb +1 -1
- data/lib/rubocop/directive_comment.rb +1 -1
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/lsp/runtime.rb +4 -4
- data/lib/rubocop/lsp/stdin_runner.rb +3 -1
- data/lib/rubocop/rspec/cop_helper.rb +4 -1
- data/lib/rubocop/rspec/shared_contexts.rb +20 -0
- data/lib/rubocop/rspec/support.rb +2 -0
- data/lib/rubocop/runner.rb +5 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +14 -7
- data/lib/rubocop.rb +5 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +20 -2
- metadata +12 -6
@@ -75,6 +75,7 @@ module RuboCop
|
|
75
75
|
check_for_breakable_block(node)
|
76
76
|
end
|
77
77
|
alias on_numblock on_block
|
78
|
+
alias on_itblock on_block
|
78
79
|
|
79
80
|
def on_str(node)
|
80
81
|
check_for_breakable_str(node)
|
@@ -92,6 +93,7 @@ module RuboCop
|
|
92
93
|
alias on_send on_potential_breakable_node
|
93
94
|
alias on_csend on_potential_breakable_node
|
94
95
|
alias on_def on_potential_breakable_node
|
96
|
+
alias on_defs on_potential_breakable_node
|
95
97
|
|
96
98
|
def on_new_investigation
|
97
99
|
return unless processed_source.raw_source.include?(';')
|
@@ -370,7 +372,9 @@ module RuboCop
|
|
370
372
|
|
371
373
|
def string_delimiter(node)
|
372
374
|
delimiter = node.loc.begin
|
373
|
-
|
375
|
+
if node.parent&.dstr_type? && node.parent.loc.respond_to?(:begin)
|
376
|
+
delimiter ||= node.parent.loc.begin
|
377
|
+
end
|
374
378
|
delimiter = delimiter&.source
|
375
379
|
|
376
380
|
delimiter if %w[' "].include?(delimiter)
|
@@ -6,25 +6,29 @@ module RuboCop
|
|
6
6
|
# Checks whether certain expressions, e.g. method calls, that could fit
|
7
7
|
# completely on a single line, are broken up into multiple lines unnecessarily.
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example
|
10
10
|
# # bad
|
11
11
|
# foo(
|
12
12
|
# a,
|
13
13
|
# b
|
14
14
|
# )
|
15
15
|
#
|
16
|
+
# # good
|
17
|
+
# foo(a, b)
|
18
|
+
#
|
19
|
+
# # bad
|
16
20
|
# puts 'string that fits on ' \
|
17
21
|
# 'a single line'
|
18
22
|
#
|
23
|
+
# # good
|
24
|
+
# puts 'string that fits on a single line'
|
25
|
+
#
|
26
|
+
# # bad
|
19
27
|
# things
|
20
28
|
# .select { |thing| thing.cond? }
|
21
29
|
# .join('-')
|
22
30
|
#
|
23
31
|
# # good
|
24
|
-
# foo(a, b)
|
25
|
-
#
|
26
|
-
# puts 'string that fits on a single line'
|
27
|
-
#
|
28
32
|
# things.select { |thing| thing.cond? }.join('-')
|
29
33
|
#
|
30
34
|
# @example InspectBlocks: false (default)
|
@@ -96,7 +96,7 @@ module RuboCop
|
|
96
96
|
def alignment_source(node, starting_loc)
|
97
97
|
ending_loc =
|
98
98
|
case node.type
|
99
|
-
when :block, :numblock, :kwbegin
|
99
|
+
when :block, :numblock, :itblock, :kwbegin
|
100
100
|
node.loc.begin
|
101
101
|
when :def, :defs, :class, :module,
|
102
102
|
:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
|
@@ -260,7 +260,10 @@ module RuboCop
|
|
260
260
|
end
|
261
261
|
|
262
262
|
def hash_table_style?
|
263
|
-
|
263
|
+
return false unless align_hash_cop_config
|
264
|
+
|
265
|
+
enforced_styles = Array(align_hash_cop_config['EnforcedHashRocketStyle'])
|
266
|
+
enforced_styles.include?('table')
|
264
267
|
end
|
265
268
|
|
266
269
|
def space_around_exponent_operator?
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
# require 'my_debugger/start'
|
74
74
|
class Debugger < Base
|
75
75
|
MSG = 'Remove debugger entry point `%<source>s`.'
|
76
|
-
BLOCK_TYPES = %i[block numblock kwbegin].freeze
|
76
|
+
BLOCK_TYPES = %i[block numblock itblock kwbegin].freeze
|
77
77
|
|
78
78
|
def on_send(node)
|
79
79
|
return if assumed_usage_context?(node)
|
@@ -120,7 +120,7 @@ module RuboCop
|
|
120
120
|
return true if assumed_argument?(node)
|
121
121
|
|
122
122
|
node.each_ancestor.none? do |ancestor|
|
123
|
-
|
123
|
+
ancestor.type?(:any_block, :kwbegin) || ancestor.lambda_or_proc?
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -7,11 +7,6 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# NOTE: empty `else` branches are handled by `Style/EmptyElse`.
|
9
9
|
#
|
10
|
-
# @safety
|
11
|
-
# Autocorrection for this cop is not safe. The conditions for empty branches that
|
12
|
-
# the autocorrection removes may have side effects, or the logic in subsequent
|
13
|
-
# branches may change due to the removal of a previous condition.
|
14
|
-
#
|
15
10
|
# @example
|
16
11
|
# # bad
|
17
12
|
# if condition
|
@@ -41,6 +36,13 @@ module RuboCop
|
|
41
36
|
# if condition
|
42
37
|
# do_something
|
43
38
|
# elsif other_condition
|
39
|
+
# nil
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# if condition
|
44
|
+
# do_something
|
45
|
+
# elsif other_condition
|
44
46
|
# do_something_else
|
45
47
|
# end
|
46
48
|
#
|
@@ -63,7 +65,6 @@ module RuboCop
|
|
63
65
|
class EmptyConditionalBody < Base
|
64
66
|
extend AutoCorrector
|
65
67
|
include CommentsHelp
|
66
|
-
include RangeHelp
|
67
68
|
|
68
69
|
MSG = 'Avoid `%<keyword>s` branches without a body.'
|
69
70
|
|
@@ -74,21 +75,14 @@ module RuboCop
|
|
74
75
|
range = offense_range(node)
|
75
76
|
|
76
77
|
add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector|
|
77
|
-
|
78
|
+
next unless can_simplify_conditional?(node)
|
79
|
+
|
80
|
+
flip_orphaned_else(corrector, node)
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
81
84
|
private
|
82
85
|
|
83
|
-
def do_autocorrect?(node)
|
84
|
-
# if condition; end.do_something
|
85
|
-
return false if (parent = node.parent)&.call_type?
|
86
|
-
# x = if condition; end
|
87
|
-
return false if (parent&.assignment? || parent&.operator_keyword?) && node.children.one?
|
88
|
-
|
89
|
-
true
|
90
|
-
end
|
91
|
-
|
92
86
|
def offense_range(node)
|
93
87
|
if node.loc.else
|
94
88
|
node.source_range.begin.join(node.loc.else.begin)
|
@@ -97,53 +91,23 @@ module RuboCop
|
|
97
91
|
end
|
98
92
|
end
|
99
93
|
|
100
|
-
def
|
101
|
-
|
102
|
-
remove_empty_branch(corrector, node)
|
103
|
-
correct_other_branches(corrector, node)
|
104
|
-
end
|
105
|
-
|
106
|
-
def remove_comments(corrector, node)
|
107
|
-
comments_in_range(node).each do |comment|
|
108
|
-
range = range_by_whole_lines(comment.source_range, include_final_newline: true)
|
109
|
-
corrector.remove(range)
|
110
|
-
end
|
94
|
+
def can_simplify_conditional?(node)
|
95
|
+
node.else_branch && node.loc.else.source == 'else'
|
111
96
|
end
|
112
97
|
|
113
|
-
# rubocop:disable Metrics/AbcSize
|
114
98
|
def remove_empty_branch(corrector, node)
|
115
99
|
range = if empty_if_branch?(node) && else_branch?(node)
|
116
100
|
branch_range(node)
|
117
|
-
elsif same_line?(node, else_kw_loc = node.loc.else)
|
118
|
-
node.source_range.begin.join(else_kw_loc.begin)
|
119
|
-
elsif node.parent&.loc.respond_to?(:end) &&
|
120
|
-
same_line?(node, end_loc = node.parent.loc.end)
|
121
|
-
node.source_range.begin.join(end_loc.begin)
|
122
101
|
else
|
123
102
|
deletion_range(branch_range(node))
|
124
103
|
end
|
125
104
|
|
126
105
|
corrector.remove(range)
|
127
106
|
end
|
128
|
-
# rubocop:enable Metrics/AbcSize
|
129
107
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
if node.else_branch&.if_type? && !node.else_branch.modifier_form?
|
134
|
-
# Replace an orphaned `elsif` with `if`
|
135
|
-
corrector.replace(node.else_branch.loc.keyword, 'if')
|
136
|
-
else
|
137
|
-
# Flip orphaned `else`
|
138
|
-
corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def require_other_branches_correction?(node)
|
143
|
-
return false unless node.if_type? && node.else?
|
144
|
-
return false if !empty_if_branch?(node) && node.elsif?
|
145
|
-
|
146
|
-
!empty_elsif_branch?(node)
|
108
|
+
def flip_orphaned_else(corrector, node)
|
109
|
+
corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
|
110
|
+
remove_empty_branch(corrector, node)
|
147
111
|
end
|
148
112
|
|
149
113
|
def empty_if_branch?(node)
|
@@ -154,36 +118,17 @@ module RuboCop
|
|
154
118
|
if_branch.if_type? && !if_branch.body
|
155
119
|
end
|
156
120
|
|
157
|
-
def empty_elsif_branch?(node)
|
158
|
-
return false unless (else_branch = node.else_branch)
|
159
|
-
|
160
|
-
else_branch.if_type? && !else_branch.body
|
161
|
-
end
|
162
|
-
|
163
121
|
def else_branch?(node)
|
164
122
|
node.else_branch && !node.else_branch.if_type?
|
165
123
|
end
|
166
124
|
|
167
|
-
# rubocop:disable Metrics/AbcSize
|
168
125
|
def branch_range(node)
|
169
126
|
if empty_if_branch?(node) && else_branch?(node)
|
170
127
|
node.source_range.with(end_pos: node.loc.else.begin_pos)
|
171
128
|
elsif node.loc.else
|
172
129
|
node.source_range.with(end_pos: node.condition.source_range.end_pos)
|
173
|
-
elsif all_branches_body_missing?(node)
|
174
|
-
if_node = node.ancestors.detect(&:if?)
|
175
|
-
node.source_range.join(if_node.loc.end.end)
|
176
|
-
else
|
177
|
-
node.source_range
|
178
130
|
end
|
179
131
|
end
|
180
|
-
# rubocop:enable Metrics/AbcSize
|
181
|
-
|
182
|
-
def all_branches_body_missing?(node)
|
183
|
-
return false unless node.parent&.if_type?
|
184
|
-
|
185
|
-
node.parent.branches.compact.empty?
|
186
|
-
end
|
187
132
|
|
188
133
|
def deletion_range(range)
|
189
134
|
# Collect a range between the start of the `if` node and the next relevant node,
|
@@ -156,12 +156,6 @@ module RuboCop
|
|
156
156
|
|
157
157
|
overridden_kwargs
|
158
158
|
end
|
159
|
-
|
160
|
-
def arguments_range(node)
|
161
|
-
arguments = node.arguments
|
162
|
-
|
163
|
-
range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos)
|
164
|
-
end
|
165
159
|
end
|
166
160
|
end
|
167
161
|
end
|
@@ -46,6 +46,10 @@ module RuboCop
|
|
46
46
|
return unless node.lhs.truthy_literal?
|
47
47
|
|
48
48
|
add_offense(node.lhs) do |corrector|
|
49
|
+
# Don't autocorrect `'foo' && return` because having `return` as
|
50
|
+
# the leftmost node can lead to a void value expression syntax error.
|
51
|
+
next if node.rhs.type?(:return, :break, :next)
|
52
|
+
|
49
53
|
corrector.replace(node, node.rhs.source)
|
50
54
|
end
|
51
55
|
end
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
def on_return(return_node)
|
47
47
|
return if return_value?(return_node)
|
48
48
|
|
49
|
-
return_node.each_ancestor(:
|
49
|
+
return_node.each_ancestor(:any_block, :def, :defs) do |node|
|
50
50
|
break if scoped_node?(node)
|
51
51
|
|
52
52
|
# if a proc is passed to `Module#define_method` or
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
54
54
|
# non-local exit error
|
55
55
|
break if define_method?(node.send_node)
|
56
56
|
|
57
|
-
next
|
57
|
+
next if node.argument_list.empty?
|
58
58
|
|
59
59
|
if chained_send?(node.send_node)
|
60
60
|
add_offense(return_node.loc.keyword)
|
@@ -3,15 +3,18 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for `raise` or `fail` statements which
|
7
|
-
#
|
6
|
+
# Checks for `raise` or `fail` statements which raise `Exception` or
|
7
|
+
# `Exception.new`. Use `StandardError` or a specific exception class instead.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
9
|
+
# If you have defined your own namespaced `Exception` class, it is possible
|
10
|
+
# to configure the cop to allow it by setting `AllowedImplicitNamespaces` to
|
11
|
+
# an array with the names of the namespaces to allow. By default, this is set to
|
12
|
+
# `['Gem']`, which allows `Gem::Exception` to be raised without an explicit namespace.
|
13
|
+
# If not allowed, a false positive may be registered if `raise Exception` is called
|
14
|
+
# within the namespace.
|
15
|
+
#
|
16
|
+
# Alternatively, use a fully qualified name with `raise`/`fail`
|
17
|
+
# (eg. `raise Namespace::Exception`).
|
15
18
|
#
|
16
19
|
# @safety
|
17
20
|
# This cop is unsafe because it will change the exception class being
|
@@ -20,15 +23,31 @@ module RuboCop
|
|
20
23
|
# @example
|
21
24
|
# # bad
|
22
25
|
# raise Exception, 'Error message here'
|
26
|
+
# raise Exception.new('Error message here')
|
23
27
|
#
|
24
28
|
# # good
|
25
29
|
# raise StandardError, 'Error message here'
|
30
|
+
# raise MyError.new, 'Error message here'
|
31
|
+
#
|
32
|
+
# @example AllowedImplicitNamespaces: ['Gem'] (default)
|
33
|
+
# # bad - `Foo` is not an allowed implicit namespace
|
34
|
+
# module Foo
|
35
|
+
# def self.foo
|
36
|
+
# raise Exception # This is qualified to `Foo::Exception`.
|
37
|
+
# end
|
38
|
+
# end
|
26
39
|
#
|
27
|
-
# @example AllowedImplicitNamespaces: ['Gem']
|
28
40
|
# # good
|
29
41
|
# module Gem
|
30
42
|
# def self.foo
|
31
|
-
# raise Exception # This
|
43
|
+
# raise Exception # This is qualified to `Gem::Exception`.
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
# module Foo
|
49
|
+
# def self.foo
|
50
|
+
# raise Foo::Exception
|
32
51
|
# end
|
33
52
|
# end
|
34
53
|
class RaiseException < Base
|
@@ -3,13 +3,13 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_r`, `to_c`,
|
6
|
+
# Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_d`, `to_r`, `to_c`,
|
7
7
|
# `to_a`, `to_h`, and `to_set`.
|
8
8
|
#
|
9
9
|
# When one of these methods is called on an object of the same type, that object
|
10
10
|
# is returned, making the call unnecessary. The cop detects conversion methods called
|
11
11
|
# on object literals, class constructors, class `[]` methods, and the `Kernel` methods
|
12
|
-
# `String()`, `Integer()`, `Float()`, `Rational()`, `Complex()
|
12
|
+
# `String()`, `Integer()`, `Float()`, BigDecimal(), `Rational()`, `Complex()`, and `Array()`.
|
13
13
|
#
|
14
14
|
# Specifically, these cases are detected for each conversion method:
|
15
15
|
#
|
@@ -98,6 +98,7 @@ module RuboCop
|
|
98
98
|
to_s: 'string_constructor?',
|
99
99
|
to_i: 'integer_constructor?',
|
100
100
|
to_f: 'float_constructor?',
|
101
|
+
to_d: 'bigdecimal_constructor?',
|
101
102
|
to_r: 'rational_constructor?',
|
102
103
|
to_c: 'complex_constructor?',
|
103
104
|
to_a: 'array_constructor?',
|
@@ -110,7 +111,7 @@ module RuboCop
|
|
110
111
|
TYPED_METHODS = { to_s: %i[inspect] }.freeze
|
111
112
|
|
112
113
|
CONVERSION_METHODS = Set[*LITERAL_NODE_TYPES.keys].freeze
|
113
|
-
RESTRICT_ON_SEND = CONVERSION_METHODS
|
114
|
+
RESTRICT_ON_SEND = CONVERSION_METHODS + [:to_d]
|
114
115
|
|
115
116
|
private_constant :LITERAL_NODE_TYPES, :CONSTRUCTOR_MAPPING
|
116
117
|
|
@@ -137,6 +138,11 @@ module RuboCop
|
|
137
138
|
#type_constructor?(:Float)
|
138
139
|
PATTERN
|
139
140
|
|
141
|
+
# @!method bigdecimal_constructor?(node)
|
142
|
+
def_node_matcher :bigdecimal_constructor?, <<~PATTERN
|
143
|
+
#type_constructor?(:BigDecimal)
|
144
|
+
PATTERN
|
145
|
+
|
140
146
|
# @!method rational_constructor?(node)
|
141
147
|
def_node_matcher :rational_constructor?, <<~PATTERN
|
142
148
|
#type_constructor?(:Rational)
|
@@ -53,6 +53,7 @@ module RuboCop
|
|
53
53
|
# rubocop:enable Metrics/AbcSize
|
54
54
|
|
55
55
|
alias on_numblock on_block
|
56
|
+
alias on_itblock on_block
|
56
57
|
|
57
58
|
private
|
58
59
|
|
@@ -64,6 +65,8 @@ module RuboCop
|
|
64
65
|
(args (arg _)) ...)
|
65
66
|
(numblock
|
66
67
|
$(call _ {:each_with_index :with_index} ...) 1 ...)
|
68
|
+
(itblock
|
69
|
+
$(call _ {:each_with_index :with_index} ...) _ ...)
|
67
70
|
}
|
68
71
|
PATTERN
|
69
72
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
49
49
|
end
|
50
50
|
|
51
51
|
alias on_numblock on_block
|
52
|
+
alias on_itblock on_block
|
52
53
|
|
53
54
|
private
|
54
55
|
|
@@ -59,6 +60,8 @@ module RuboCop
|
|
59
60
|
$(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
|
60
61
|
(numblock
|
61
62
|
$(call _ {:each_with_object :with_object} _) 1 ...)
|
63
|
+
(itblock
|
64
|
+
$(call _ {:each_with_object :with_object} _) _ ...)
|
62
65
|
}
|
63
66
|
PATTERN
|
64
67
|
|
@@ -35,22 +35,15 @@ module RuboCop
|
|
35
35
|
def on_return(return_node)
|
36
36
|
return unless return_node.descendants.any?
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
return
|
41
|
-
return unless context_node&.void_context?
|
38
|
+
def_node = return_node.each_ancestor(:def).first
|
39
|
+
return unless def_node&.void_context?
|
40
|
+
return if return_node.each_ancestor(:any_block).any?(&:lambda?)
|
42
41
|
|
43
42
|
add_offense(
|
44
43
|
return_node.loc.keyword,
|
45
|
-
message: format(message, method:
|
44
|
+
message: format(message, method: def_node.method_name)
|
46
45
|
)
|
47
46
|
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def non_void_context(return_node)
|
52
|
-
return_node.each_ancestor(:block, :def, :defs).first
|
53
|
-
end
|
54
47
|
end
|
55
48
|
end
|
56
49
|
end
|
@@ -56,19 +56,26 @@ module RuboCop
|
|
56
56
|
|
57
57
|
outer_local_variable = variable_table.find_variable(variable.name)
|
58
58
|
return unless outer_local_variable
|
59
|
+
return if variable_used_in_declaration_of_outer?(variable, outer_local_variable)
|
59
60
|
return if same_conditions_node_different_branch?(variable, outer_local_variable)
|
60
61
|
|
61
62
|
message = format(MSG, variable: variable.name)
|
62
63
|
add_offense(variable.declaration_node, message: message)
|
63
64
|
end
|
64
65
|
|
66
|
+
private
|
67
|
+
|
68
|
+
def variable_used_in_declaration_of_outer?(variable, outer_local_variable)
|
69
|
+
variable.scope.node.each_ancestor.any?(outer_local_variable.declaration_node)
|
70
|
+
end
|
71
|
+
|
65
72
|
def same_conditions_node_different_branch?(variable, outer_local_variable)
|
66
73
|
variable_node = variable_node(variable)
|
67
74
|
return false unless node_or_its_ascendant_conditional?(variable_node)
|
68
75
|
|
69
76
|
outer_local_variable_node =
|
70
77
|
find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
|
71
|
-
return
|
78
|
+
return false unless outer_local_variable_node
|
72
79
|
return false unless outer_local_variable_node.conditional?
|
73
80
|
return true if variable_node == outer_local_variable_node
|
74
81
|
|
@@ -51,7 +51,18 @@ module RuboCop
|
|
51
51
|
|
52
52
|
# @!method hash_initialized_with_mutable_shared_object?(node)
|
53
53
|
def_node_matcher :hash_initialized_with_mutable_shared_object?, <<~PATTERN
|
54
|
-
|
54
|
+
{
|
55
|
+
(send (const {nil? cbase} :Hash) :new [
|
56
|
+
{array hash (send (const {nil? cbase} {:Array :Hash}) :new)}
|
57
|
+
!#capacity_keyword_argument?
|
58
|
+
])
|
59
|
+
(send (const {nil? cbase} :Hash) :new hash #capacity_keyword_argument?)
|
60
|
+
}
|
61
|
+
PATTERN
|
62
|
+
|
63
|
+
# @!method capacity_keyword_argument?(node)
|
64
|
+
def_node_matcher :capacity_keyword_argument?, <<~PATTERN
|
65
|
+
(hash (pair (sym :capacity) _))
|
55
66
|
PATTERN
|
56
67
|
|
57
68
|
def on_send(node)
|
@@ -53,6 +53,7 @@ module RuboCop
|
|
53
53
|
end
|
54
54
|
|
55
55
|
alias on_numblock on_block
|
56
|
+
alias on_itblock on_block
|
56
57
|
|
57
58
|
private
|
58
59
|
|
@@ -74,6 +75,7 @@ module RuboCop
|
|
74
75
|
|
75
76
|
def arg_count(node)
|
76
77
|
return node.children[1] if node.numblock_type? # the maximum numbered param for the block
|
78
|
+
return 1 if node.itblock_type? # `it` block parameter is always one
|
77
79
|
|
78
80
|
# Only `arg`, `optarg` and `mlhs` (destructuring) count as arguments that
|
79
81
|
# can be used. Keyword arguments are not used for these methods so are
|
@@ -101,9 +101,8 @@ module RuboCop
|
|
101
101
|
check(node) if loop_method?(node)
|
102
102
|
end
|
103
103
|
|
104
|
-
|
105
|
-
|
106
|
-
end
|
104
|
+
alias on_numblock on_block
|
105
|
+
alias on_itblock on_block
|
107
106
|
|
108
107
|
private
|
109
108
|
|
@@ -189,8 +188,9 @@ module RuboCop
|
|
189
188
|
|
190
189
|
def preceded_by_continue_statement?(break_statement)
|
191
190
|
break_statement.left_siblings.any? do |sibling|
|
192
|
-
# Numblocks have the arguments count as a number
|
193
|
-
|
191
|
+
# Numblocks have the arguments count as a number or,
|
192
|
+
# itblocks have `:it` symbol in the AST.
|
193
|
+
next if sibling.is_a?(Integer) || sibling.is_a?(Symbol)
|
194
194
|
next if sibling.loop_keyword? || loop_method?(sibling)
|
195
195
|
|
196
196
|
sibling.each_descendant(*CONTINUE_KEYWORDS).any?
|