rubocop 1.45.1 → 1.48.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +28 -9
- data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
- data/lib/rubocop/comment_config.rb +19 -0
- data/lib/rubocop/config.rb +2 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/gemspec/dependency_version.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +39 -0
- data/lib/rubocop/cop/internal_affairs.rb +3 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +7 -21
- data/lib/rubocop/cop/layout/class_structure.rb +5 -3
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +8 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -3
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -7
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +3 -0
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -3
- data/lib/rubocop/cop/lint/else_layout.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +46 -4
- data/lib/rubocop/cop/lint/missing_super.rb +31 -2
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -9
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +6 -10
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +10 -4
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +6 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +10 -10
- data/lib/rubocop/cop/lint/useless_rescue.rb +6 -2
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +2 -2
- data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +10 -5
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +1 -6
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +3 -3
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/registry.rb +3 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +39 -17
- data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -3
- data/lib/rubocop/cop/style/array_intersect.rb +1 -1
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +11 -2
- data/lib/rubocop/cop/style/case_like_if.rb +20 -3
- data/lib/rubocop/cop/style/collection_compact.rb +1 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +10 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -6
- data/lib/rubocop/cop/style/dir_empty.rb +60 -0
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +10 -4
- data/lib/rubocop/cop/style/documentation_method.rb +4 -4
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/file_empty.rb +71 -0
- data/lib/rubocop/cop/style/file_read.rb +1 -1
- data/lib/rubocop/cop/style/file_write.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +1 -1
- data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +76 -9
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
- data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +2 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/min_max.rb +3 -3
- data/lib/rubocop/cop/style/mixin_grouping.rb +4 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +12 -7
- data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +2 -2
- data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +5 -6
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +10 -3
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/require_order.rb +1 -3
- data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
- data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
- data/lib/rubocop/cop/style/unpack_first.rb +3 -3
- data/lib/rubocop/cop/style/word_array.rb +17 -5
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
- data/lib/rubocop/cop/team.rb +11 -8
- data/lib/rubocop/cop/util.rb +13 -4
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/directive_comment.rb +3 -3
- data/lib/rubocop/ext/comment.rb +18 -0
- data/lib/rubocop/formatter/junit_formatter.rb +4 -1
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/server/core.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +17 -9
@@ -231,7 +231,7 @@ module RuboCop
|
|
231
231
|
cop_names = cops.sort.map { |c| describe(c) }.join(', ')
|
232
232
|
|
233
233
|
add_offense(location, message: message(cop_names)) do |corrector|
|
234
|
-
range = comment_range_with_surrounding_space(location, comment.
|
234
|
+
range = comment_range_with_surrounding_space(location, comment.source_range)
|
235
235
|
|
236
236
|
if leave_free_comment?(comment, range)
|
237
237
|
corrector.replace(range, ' # ')
|
@@ -263,8 +263,8 @@ module RuboCop
|
|
263
263
|
|
264
264
|
def cop_range(comment, cop)
|
265
265
|
cop = remove_department_marker(cop)
|
266
|
-
matching_range(comment.
|
267
|
-
matching_range(comment.
|
266
|
+
matching_range(comment.source_range, cop) ||
|
267
|
+
matching_range(comment.source_range, Badge.parse(cop).cop_name) ||
|
268
268
|
raise("Couldn't find #{cop} in comment: #{comment.text}")
|
269
269
|
end
|
270
270
|
|
@@ -284,12 +284,18 @@ module RuboCop
|
|
284
284
|
.all? { |intervening| /\A\s*,\s*\Z/.match?(intervening) }
|
285
285
|
end
|
286
286
|
|
287
|
+
SIMILAR_COP_NAMES_CACHE = Hash.new do |hash, cop_name|
|
288
|
+
hash[:all_cop_names] = Registry.global.names unless hash.key?(:all_cop_names)
|
289
|
+
hash[cop_name] = NameSimilarity.find_similar_name(cop_name, hash[:all_cop_names])
|
290
|
+
end
|
291
|
+
private_constant :SIMILAR_COP_NAMES_CACHE
|
292
|
+
|
287
293
|
def describe(cop)
|
288
294
|
return 'all cops' if cop == 'all'
|
289
295
|
return "`#{remove_department_marker(cop)}` department" if department_marker?(cop)
|
290
296
|
return "`#{cop}`" if all_cop_names.include?(cop)
|
291
297
|
|
292
|
-
similar =
|
298
|
+
similar = SIMILAR_COP_NAMES_CACHE[cop]
|
293
299
|
similar ? "`#{cop}` (did you mean `#{similar}`?)" : "`#{cop}` (unknown cop)"
|
294
300
|
end
|
295
301
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def comment_start(comment)
|
77
|
-
comment.
|
77
|
+
comment.source_range.begin_pos
|
78
78
|
end
|
79
79
|
|
80
80
|
def cop_name_indention(comment, name)
|
@@ -82,7 +82,7 @@ module RuboCop
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def range_with_comma(comment, name)
|
85
|
-
source = comment.
|
85
|
+
source = comment.source
|
86
86
|
|
87
87
|
begin_pos = cop_name_indention(comment, name)
|
88
88
|
end_pos = begin_pos + name.size
|
@@ -94,14 +94,14 @@ module RuboCop
|
|
94
94
|
|
95
95
|
def range_to_remove(begin_pos, end_pos, comment)
|
96
96
|
start = comment_start(comment)
|
97
|
-
source = comment.
|
97
|
+
source = comment.source
|
98
98
|
|
99
99
|
if source[begin_pos - 1] == ','
|
100
100
|
range_with_comma_before(start, begin_pos, end_pos)
|
101
101
|
elsif source[end_pos] == ','
|
102
102
|
range_with_comma_after(comment, start, begin_pos, end_pos)
|
103
103
|
else
|
104
|
-
range_between(start, comment.
|
104
|
+
range_between(start, comment.source_range.end_pos)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
@@ -112,7 +112,7 @@ module RuboCop
|
|
112
112
|
# If the list of cops is comma-separated, but without a empty space after the comma,
|
113
113
|
# we should **not** remove the prepending empty space, thus begin_pos += 1
|
114
114
|
def range_with_comma_after(comment, start, begin_pos, end_pos)
|
115
|
-
begin_pos += 1 if comment.
|
115
|
+
begin_pos += 1 if comment.source[end_pos + 1] != ' '
|
116
116
|
|
117
117
|
range_between(start + begin_pos, start + end_pos + 1)
|
118
118
|
end
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
56
56
|
if node.parent.respond_to?(:modifier_form?) && node.parent.modifier_form?
|
57
57
|
corrector.insert_after(node.parent, "\nend")
|
58
58
|
|
59
|
-
range = range_with_surrounding_space(node.
|
59
|
+
range = range_with_surrounding_space(node.source_range, side: :right)
|
60
60
|
else
|
61
61
|
range = range_by_whole_lines(node.source_range, include_final_newline: true)
|
62
62
|
end
|
@@ -141,7 +141,7 @@ module RuboCop
|
|
141
141
|
expression = loc.expression
|
142
142
|
|
143
143
|
if array_new?(variable)
|
144
|
-
expression = node.parent.
|
144
|
+
expression = node.parent.source_range if node.parent.array_type?
|
145
145
|
[expression, variable.source]
|
146
146
|
elsif !variable.array_type?
|
147
147
|
[expression, "[#{variable.source}]"]
|
@@ -41,7 +41,8 @@ module RuboCop
|
|
41
41
|
|
42
42
|
def on_send(node)
|
43
43
|
return if node.receiver
|
44
|
-
return unless
|
44
|
+
return unless (parent = node.parent)
|
45
|
+
return unless parent.block_type? && parent.method?(:refine)
|
45
46
|
|
46
47
|
add_offense(node.loc.selector, message: format(MSG, current: node.method_name))
|
47
48
|
end
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
50
50
|
return if invalid_exceptions.empty?
|
51
51
|
|
52
52
|
add_offense(
|
53
|
-
node.loc.keyword.join(rescued.
|
53
|
+
node.loc.keyword.join(rescued.source_range),
|
54
54
|
message: format(MSG, invalid_exceptions: invalid_exceptions.map(&:source).join(', '))
|
55
55
|
) do |corrector|
|
56
56
|
autocorrect(corrector, node)
|
@@ -59,9 +59,9 @@ module RuboCop
|
|
59
59
|
|
60
60
|
def autocorrect(corrector, node)
|
61
61
|
rescued, _, _body = *node
|
62
|
-
range = Parser::Source::Range.new(node.
|
62
|
+
range = Parser::Source::Range.new(node.source_range.source_buffer,
|
63
63
|
node.loc.keyword.end_pos,
|
64
|
-
rescued.
|
64
|
+
rescued.source_range.end_pos)
|
65
65
|
|
66
66
|
corrector.replace(range, correction(*rescued))
|
67
67
|
end
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
83
83
|
|
84
84
|
def offense_range(rescues)
|
85
85
|
shadowing_rescue = find_shadowing_rescue(rescues)
|
86
|
-
expression = shadowing_rescue.
|
86
|
+
expression = shadowing_rescue.source_range
|
87
87
|
range_between(expression.begin_pos, expression.end_pos)
|
88
88
|
end
|
89
89
|
|
@@ -43,8 +43,12 @@ module RuboCop
|
|
43
43
|
return unless def_node
|
44
44
|
|
45
45
|
enum_conversion_call?(node) do |method_node, arguments|
|
46
|
-
|
47
|
-
|
46
|
+
next if method_node.call_type? &&
|
47
|
+
!method_node.method?(:__method__) && !method_node.method?(:__callee__)
|
48
|
+
next if method_name?(method_node, def_node.method_name) &&
|
49
|
+
arguments_match?(arguments, def_node)
|
50
|
+
|
51
|
+
add_offense(node)
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -137,7 +137,7 @@ module RuboCop
|
|
137
137
|
alias on_sclass on_class
|
138
138
|
|
139
139
|
def on_block(node)
|
140
|
-
return unless eval_call?(node)
|
140
|
+
return unless eval_call?(node) || included_block?(node)
|
141
141
|
|
142
142
|
check_node(node.body)
|
143
143
|
end
|
@@ -167,14 +167,6 @@ module RuboCop
|
|
167
167
|
({block numblock} (send _ {:class_eval :instance_eval}) ...)
|
168
168
|
PATTERN
|
169
169
|
|
170
|
-
# @!method class_constructor?(node)
|
171
|
-
def_node_matcher :class_constructor?, <<~PATTERN
|
172
|
-
({block numblock} {
|
173
|
-
(send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
|
174
|
-
(send (const {nil? cbase} :Data) :define ...)
|
175
|
-
} ...)
|
176
|
-
PATTERN
|
177
|
-
|
178
170
|
def check_node(node)
|
179
171
|
return if node.nil?
|
180
172
|
|
@@ -200,10 +192,13 @@ module RuboCop
|
|
200
192
|
end
|
201
193
|
end
|
202
194
|
|
195
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
203
196
|
def check_child_nodes(node, unused, cur_vis)
|
204
197
|
node.child_nodes.each do |child|
|
205
198
|
if child.send_type? && access_modifier?(child)
|
206
199
|
cur_vis, unused = check_send_node(child, cur_vis, unused)
|
200
|
+
elsif child.block_type? && included_block?(child)
|
201
|
+
next
|
207
202
|
elsif method_definition?(child)
|
208
203
|
unused = nil
|
209
204
|
elsif start_of_new_scope?(child)
|
@@ -215,6 +210,7 @@ module RuboCop
|
|
215
210
|
|
216
211
|
[cur_vis, unused]
|
217
212
|
end
|
213
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
218
214
|
|
219
215
|
def check_send_node(node, cur_vis, unused)
|
220
216
|
if node.bare_access_modifier?
|
@@ -248,6 +244,10 @@ module RuboCop
|
|
248
244
|
[new_vis, unused]
|
249
245
|
end
|
250
246
|
|
247
|
+
def included_block?(block_node)
|
248
|
+
active_support_extensions_enabled? && block_node.method?(:included)
|
249
|
+
end
|
250
|
+
|
251
251
|
def method_definition?(child)
|
252
252
|
static_method_definition?(child) ||
|
253
253
|
dynamic_method_definition?(child) ||
|
@@ -273,7 +273,7 @@ module RuboCop
|
|
273
273
|
|
274
274
|
def eval_call?(child)
|
275
275
|
class_or_instance_eval?(child) ||
|
276
|
-
class_constructor?
|
276
|
+
child.class_constructor? ||
|
277
277
|
any_context_creating_methods?(child)
|
278
278
|
end
|
279
279
|
|
@@ -56,11 +56,13 @@ module RuboCop
|
|
56
56
|
|
57
57
|
private
|
58
58
|
|
59
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
59
60
|
def only_reraising?(resbody_node)
|
60
61
|
return false if use_exception_variable_in_ensure?(resbody_node)
|
61
62
|
|
62
63
|
body = resbody_node.body
|
63
|
-
|
64
|
+
|
65
|
+
return false if body.nil? || !body.send_type? || !body.method?(:raise) || body.receiver
|
64
66
|
return true unless body.arguments?
|
65
67
|
return false if body.arguments.size > 1
|
66
68
|
|
@@ -68,12 +70,14 @@ module RuboCop
|
|
68
70
|
|
69
71
|
exception_objects(resbody_node).include?(exception_name)
|
70
72
|
end
|
73
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
71
74
|
|
72
75
|
def use_exception_variable_in_ensure?(resbody_node)
|
73
76
|
return false unless (exception_variable = resbody_node.exception_variable)
|
74
77
|
return false unless (ensure_node = resbody_node.each_ancestor(:ensure).first)
|
78
|
+
return false unless (ensure_body = ensure_node.body)
|
75
79
|
|
76
|
-
|
80
|
+
ensure_body.each_descendant(:lvar).map(&:source).include?(exception_variable.source)
|
77
81
|
end
|
78
82
|
|
79
83
|
def exception_objects(resbody_node)
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def remove_node(corrector, node)
|
77
|
-
corrector.remove(range_by_whole_lines(node.
|
77
|
+
corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
|
78
78
|
end
|
79
79
|
|
80
80
|
def autocorrect_block_pass(corrector, node, proc_name)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Metrics
|
6
|
+
# Checks for literals with extremely many entries. This is indicative of
|
7
|
+
# configuration or data that may be better extracted somewhere else, like
|
8
|
+
# a database, fetched from an API, or read from a non-code file (CSV,
|
9
|
+
# JSON, YAML, etc.).
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# # bad
|
13
|
+
# # Huge Array literal
|
14
|
+
# [1, 2, '...', 999_999_999]
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# # Huge Hash literal
|
18
|
+
# { 1 => 1, 2 => 2, '...' => '...', 999_999_999 => 999_999_999}
|
19
|
+
#
|
20
|
+
# # bad
|
21
|
+
# # Huge Set "literal"
|
22
|
+
# Set[1, 2, '...', 999_999_999]
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# # Reasonably sized Array literal
|
26
|
+
# [1, 2, '...', 10]
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# # Reading huge Array from external data source
|
30
|
+
# # File.readlines('numbers.txt', chomp: true).map!(&:to_i)
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# # Reasonably sized Hash literal
|
34
|
+
# { 1 => 1, 2 => 2, '...' => '...', 10 => 10}
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# # Reading huge Hash from external data source
|
38
|
+
# CSV.foreach('numbers.csv', headers: true).each_with_object({}) do |row, hash|
|
39
|
+
# hash[row["key"].to_i] = row["value"].to_i
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# # Reasonably sized Set "literal"
|
44
|
+
# Set[1, 2, '...', 10]
|
45
|
+
#
|
46
|
+
# # good
|
47
|
+
# # Reading huge Set from external data source
|
48
|
+
# SomeFramework.config_for(:something)[:numbers].to_set
|
49
|
+
#
|
50
|
+
class CollectionLiteralLength < Base
|
51
|
+
MSG = 'Avoid hard coding large quantities of data in code. ' \
|
52
|
+
'Prefer reading the data from an external source.'
|
53
|
+
RESTRICT_ON_SEND = [:[]].freeze
|
54
|
+
|
55
|
+
def on_array(node)
|
56
|
+
add_offense(node) if node.children.length >= collection_threshold
|
57
|
+
end
|
58
|
+
alias on_hash on_array
|
59
|
+
|
60
|
+
def on_index(node)
|
61
|
+
add_offense(node) if node.arguments.length >= collection_threshold
|
62
|
+
end
|
63
|
+
|
64
|
+
def on_send(node)
|
65
|
+
on_index(node) if node.method?(:[])
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def collection_threshold
|
71
|
+
cop_config.fetch('LengthThreshold', Float::INFINITY)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -163,8 +163,8 @@ module RuboCop
|
|
163
163
|
return 0 unless parenthesized?(parent)
|
164
164
|
|
165
165
|
[
|
166
|
-
parent.loc.begin.end_pos != descendant.
|
167
|
-
parent.loc.end.begin_pos != descendant.
|
166
|
+
parent.loc.begin.end_pos != descendant.source_range.begin_pos,
|
167
|
+
parent.loc.end.begin_pos != descendant.source_range.end_pos
|
168
168
|
].count(true)
|
169
169
|
end
|
170
170
|
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def check_cop_name(name, comment, offset)
|
48
|
-
start = comment.
|
48
|
+
start = comment.source_range.begin_pos + offset
|
49
49
|
range = range_between(start, start + name.length)
|
50
50
|
|
51
51
|
add_offense(range) do |corrector|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
# Returns the range bounds for just the annotation
|
31
31
|
def bounds
|
32
|
-
start = comment.
|
32
|
+
start = comment.source_range.begin_pos + margin.length
|
33
33
|
length = [keyword, colon, space].reduce(0) { |len, elem| len + elem.to_s.length }
|
34
34
|
[start, start + length]
|
35
35
|
end
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
length = calculator.calculate
|
37
37
|
return if length <= max_length
|
38
38
|
|
39
|
-
location = node.casgn_type? ? node.loc.name : node.
|
39
|
+
location = node.casgn_type? ? node.loc.name : node.source_range
|
40
40
|
|
41
41
|
add_offense(location, message: message(length, max_length)) { self.max = length }
|
42
42
|
end
|
@@ -37,7 +37,7 @@ module RuboCop
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def end_position_for(node)
|
40
|
-
end_line = buffer.line_for_position(node.
|
40
|
+
end_line = buffer.line_for_position(node.source_range.end_pos)
|
41
41
|
buffer.line_range(end_line).end_pos
|
42
42
|
end
|
43
43
|
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
node.loc.else.line
|
69
69
|
elsif node.if_type? && node.ternary?
|
70
70
|
node.else_branch.loc.line
|
71
|
-
elsif (next_sibling = node.right_sibling)
|
71
|
+
elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node)
|
72
72
|
next_sibling.loc.line
|
73
73
|
elsif (parent = node.parent)
|
74
74
|
parent.loc.end ? parent.loc.end.line : parent.loc.line
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
23
23
|
# The args node1 & node2 may represent a RuboCop::AST::Node
|
24
24
|
# or a Parser::Source::Comment. Both respond to #loc.
|
25
25
|
def preceding_comment?(node1, node2)
|
26
|
-
node1 && node2 && precede?(node2, node1) && comment_line?(node2.
|
26
|
+
node1 && node2 && precede?(node2, node1) && comment_line?(node2.source)
|
27
27
|
end
|
28
28
|
|
29
29
|
# The args node1 & node2 may represent a RuboCop::AST::Node
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
|
34
34
|
def separator_delta(pair)
|
35
35
|
if pair.hash_rocket?
|
36
|
-
correct_separator_column = pair.key.
|
36
|
+
correct_separator_column = pair.key.source_range.end.column + 1
|
37
37
|
actual_separator_column = pair.loc.operator.column
|
38
38
|
|
39
39
|
correct_separator_column - actual_separator_column
|
@@ -100,8 +100,10 @@ module RuboCop
|
|
100
100
|
last_pair = node.parent.pairs.last
|
101
101
|
return unless last_pair.key.source == last_pair.value.source
|
102
102
|
return unless (dispatch_node = find_ancestor_method_dispatch_node(node))
|
103
|
-
return if
|
104
|
-
return
|
103
|
+
return if dispatch_node.assignment_method?
|
104
|
+
return if dispatch_node.parenthesized?
|
105
|
+
return if dispatch_node.parent && parentheses?(dispatch_node.parent)
|
106
|
+
return if last_expression?(dispatch_node) && !method_dispatch_as_argument?(dispatch_node)
|
105
107
|
|
106
108
|
def_node = node.each_ancestor(:send, :csend, :super, :yield).first
|
107
109
|
|
@@ -132,9 +134,12 @@ module RuboCop
|
|
132
134
|
ancestor.ancestors.any? { |node| node.respond_to?(:modifier_form?) && node.modifier_form? }
|
133
135
|
end
|
134
136
|
|
135
|
-
def last_expression?(
|
136
|
-
|
137
|
-
|
137
|
+
def last_expression?(node)
|
138
|
+
return false if node.right_sibling
|
139
|
+
return true unless (assignment_node = node.each_ancestor.find(&:assignment?))
|
140
|
+
return last_expression?(assignment_node.parent) if assignment_node.parent&.assignment?
|
141
|
+
|
142
|
+
!assignment_node.right_sibling
|
138
143
|
end
|
139
144
|
|
140
145
|
def method_dispatch_as_argument?(method_dispatch_node)
|
@@ -159,7 +159,7 @@ module RuboCop
|
|
159
159
|
end
|
160
160
|
|
161
161
|
def strip_prefix_and_suffix(node, corrector)
|
162
|
-
expression = node.
|
162
|
+
expression = node.source_range
|
163
163
|
corrector.remove_leading(expression, leading)
|
164
164
|
corrector.remove_trailing(expression, trailing)
|
165
165
|
end
|
@@ -175,11 +175,11 @@ module RuboCop
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def set_new_arg_name(transformed_argname, corrector)
|
178
|
-
corrector.replace(block_node.arguments.
|
178
|
+
corrector.replace(block_node.arguments.source_range, "|#{transformed_argname}|")
|
179
179
|
end
|
180
180
|
|
181
181
|
def set_new_body_expression(transforming_body_expr, corrector)
|
182
|
-
body_source = transforming_body_expr.
|
182
|
+
body_source = transforming_body_expr.source
|
183
183
|
if transforming_body_expr.hash_type? && !transforming_body_expr.braces?
|
184
184
|
body_source = "{ #{body_source} }"
|
185
185
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Common functionality for checking minimum branches count.
|
6
|
+
module MinBranchesCount
|
7
|
+
private
|
8
|
+
|
9
|
+
def min_branches_count?(node)
|
10
|
+
branches =
|
11
|
+
if node.case_type?
|
12
|
+
node.when_branches
|
13
|
+
elsif node.if_type?
|
14
|
+
if_conditional_branches(node)
|
15
|
+
else
|
16
|
+
raise ArgumentError, "Unsupported #{node.type.inspect} node type"
|
17
|
+
end
|
18
|
+
|
19
|
+
branches.size >= min_branches_count
|
20
|
+
end
|
21
|
+
|
22
|
+
def min_branches_count
|
23
|
+
length = cop_config['MinBranchesCount'] || 3
|
24
|
+
return length if length.is_a?(Integer) && length.positive?
|
25
|
+
|
26
|
+
raise 'MinBranchesCount needs to be a positive integer!'
|
27
|
+
end
|
28
|
+
|
29
|
+
def if_conditional_branches(node, branches = [])
|
30
|
+
return [] if node.nil? || !node.if_type?
|
31
|
+
|
32
|
+
branches << node.if_branch
|
33
|
+
|
34
|
+
else_branch = node.else_branch
|
35
|
+
if_conditional_branches(else_branch, branches) if else_branch&.if_type?
|
36
|
+
branches
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
def get_source_range(node, comments_as_separators)
|
11
11
|
unless comments_as_separators
|
12
12
|
first_comment = processed_source.ast_with_comments[node].first
|
13
|
-
return first_comment.
|
13
|
+
return first_comment.source_range unless first_comment.nil?
|
14
14
|
end
|
15
15
|
node.source_range
|
16
16
|
end
|
@@ -132,12 +132,7 @@ module RuboCop
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def range_with_comments(node)
|
135
|
-
ranges = [
|
136
|
-
node,
|
137
|
-
*@processed_source.ast_with_comments[node]
|
138
|
-
].map do |element|
|
139
|
-
element.location.expression
|
140
|
-
end
|
135
|
+
ranges = [node, *@processed_source.ast_with_comments[node]].map(&:source_range)
|
141
136
|
ranges.reduce do |result, range|
|
142
137
|
add_range(result, range)
|
143
138
|
end
|
@@ -65,14 +65,14 @@ module RuboCop
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def method_source(if_body)
|
68
|
-
range_between(if_body.
|
68
|
+
range_between(if_body.source_range.begin_pos, if_body.loc.selector.end_pos).source
|
69
69
|
end
|
70
70
|
|
71
71
|
def first_line_comment(node)
|
72
72
|
comment = processed_source.find_comment { |c| same_line?(c, node) }
|
73
73
|
return unless comment
|
74
74
|
|
75
|
-
comment_source = comment.
|
75
|
+
comment_source = comment.source
|
76
76
|
comment_source unless comment_disables_cop?(comment_source)
|
77
77
|
end
|
78
78
|
|
@@ -75,7 +75,7 @@ module RuboCop
|
|
75
75
|
|
76
76
|
def inside_comment?(range, comma_offset)
|
77
77
|
comment = processed_source.comment_at_line(range.line)
|
78
|
-
comment && comment.
|
78
|
+
comment && comment.source_range.begin_pos < range.begin_pos + comma_offset
|
79
79
|
end
|
80
80
|
|
81
81
|
# Returns true if the node has round/square/curly brackets.
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
38
38
|
return if correct_case_delimiters?(node)
|
39
39
|
|
40
40
|
add_offense(node.loc.heredoc_end) do |corrector|
|
41
|
-
expr = node.
|
41
|
+
expr = node.source_range
|
42
42
|
|
43
43
|
corrector.replace(expr, correct_delimiters(expr.source))
|
44
44
|
corrector.replace(node.loc.heredoc_end, correct_delimiters(delimiter_string(expr)))
|