rubocop 1.51.0 → 1.54.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 +62 -3
- data/lib/rubocop/cli/command/lsp.rb +19 -0
- data/lib/rubocop/cli.rb +3 -0
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
- data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +7 -0
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +27 -4
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -1
- data/lib/rubocop/cop/lint/debugger.rb +9 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -2
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
- data/lib/rubocop/cop/lint/missing_super.rb +34 -5
- data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +8 -3
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +4 -1
- data/lib/rubocop/cop/lint/void.rb +12 -18
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +30 -2
- data/lib/rubocop/cop/migration/department_name.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +3 -3
- data/lib/rubocop/cop/naming/variable_name.rb +6 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +5 -1
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +3 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_equality_comparison.rb +17 -39
- data/lib/rubocop/cop/style/collection_compact.rb +6 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +3 -1
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +8 -14
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -2
- data/lib/rubocop/cop/style/file_read.rb +2 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -22
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +6 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +1 -1
- data/lib/rubocop/cop/style/lambda.rb +3 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +3 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -0
- data/lib/rubocop/cop/style/require_order.rb +2 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +81 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +15 -5
- data/lib/rubocop/cop/style/signal_exception.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +100 -0
- data/lib/rubocop/cop/variable_force/assignment.rb +43 -4
- data/lib/rubocop/cop/variable_force.rb +1 -0
- data/lib/rubocop/cops_documentation_generator.rb +1 -1
- data/lib/rubocop/ext/regexp_parser.rb +4 -1
- data/lib/rubocop/lsp/logger.rb +22 -0
- data/lib/rubocop/lsp/routes.rb +231 -0
- data/lib/rubocop/lsp/runtime.rb +82 -0
- data/lib/rubocop/lsp/server.rb +66 -0
- data/lib/rubocop/lsp/severity.rb +27 -0
- data/lib/rubocop/options.rb +11 -1
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/version.rb +8 -4
- data/lib/rubocop.rb +12 -0
- metadata +36 -5
@@ -113,9 +113,15 @@ module RuboCop
|
|
113
113
|
def check_var(node)
|
114
114
|
return unless node.variable? || node.const_type?
|
115
115
|
|
116
|
-
|
117
|
-
|
118
|
-
|
116
|
+
if node.const_type? && node.special_keyword?
|
117
|
+
add_offense(node, message: format(VAR_MSG, var: node.source)) do |corrector|
|
118
|
+
autocorrect_void_expression(corrector, node)
|
119
|
+
end
|
120
|
+
else
|
121
|
+
add_offense(node.loc.name,
|
122
|
+
message: format(VAR_MSG, var: node.loc.name.source)) do |corrector|
|
123
|
+
autocorrect_void_expression(corrector, node)
|
124
|
+
end
|
119
125
|
end
|
120
126
|
end
|
121
127
|
|
@@ -123,7 +129,7 @@ module RuboCop
|
|
123
129
|
return if !node.literal? || node.xstr_type? || node.range_type?
|
124
130
|
|
125
131
|
add_offense(node, message: format(LIT_MSG, lit: node.source)) do |corrector|
|
126
|
-
|
132
|
+
autocorrect_void_expression(corrector, node)
|
127
133
|
end
|
128
134
|
end
|
129
135
|
|
@@ -131,7 +137,7 @@ module RuboCop
|
|
131
137
|
return unless node.self_type?
|
132
138
|
|
133
139
|
add_offense(node, message: SELF_MSG) do |corrector|
|
134
|
-
|
140
|
+
autocorrect_void_expression(corrector, node)
|
135
141
|
end
|
136
142
|
end
|
137
143
|
|
@@ -144,7 +150,7 @@ module RuboCop
|
|
144
150
|
end
|
145
151
|
|
146
152
|
def check_nonmutating(node)
|
147
|
-
return
|
153
|
+
return if !node.send_type? && !node.block_type? && !node.numblock_type?
|
148
154
|
|
149
155
|
method_name = node.method_name
|
150
156
|
return unless NONMUTATING_METHODS.include?(method_name)
|
@@ -181,18 +187,6 @@ module RuboCop
|
|
181
187
|
end
|
182
188
|
end
|
183
189
|
|
184
|
-
def autocorrect_void_var(corrector, node)
|
185
|
-
corrector.remove(range_with_surrounding_space(range: node.loc.name, side: :left))
|
186
|
-
end
|
187
|
-
|
188
|
-
def autocorrect_void_literal(corrector, node)
|
189
|
-
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
190
|
-
end
|
191
|
-
|
192
|
-
def autocorrect_void_self(corrector, node)
|
193
|
-
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
194
|
-
end
|
195
|
-
|
196
190
|
def autocorrect_void_expression(corrector, node)
|
197
191
|
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
198
192
|
end
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
63
63
|
types
|
64
64
|
end
|
65
65
|
|
66
|
-
def code_length(node)
|
66
|
+
def code_length(node) # rubocop:disable Metrics/MethodLength
|
67
67
|
if classlike_node?(node)
|
68
68
|
classlike_code_length(node)
|
69
69
|
elsif heredoc_node?(node)
|
@@ -72,7 +72,14 @@ module RuboCop
|
|
72
72
|
body = extract_body(node)
|
73
73
|
return 0 unless body
|
74
74
|
|
75
|
-
|
75
|
+
source =
|
76
|
+
if node_with_heredoc?(body)
|
77
|
+
source_from_node_with_heredoc(body)
|
78
|
+
else
|
79
|
+
body.source.lines
|
80
|
+
end
|
81
|
+
|
82
|
+
source.count { |line| !irrelevant_line?(line) }
|
76
83
|
end
|
77
84
|
end
|
78
85
|
|
@@ -175,6 +182,27 @@ module RuboCop
|
|
175
182
|
def another_args?(node)
|
176
183
|
node.call_type? && node.arguments.count > 1
|
177
184
|
end
|
185
|
+
|
186
|
+
def node_with_heredoc?(node)
|
187
|
+
node.each_descendant(:str, :dstr).any? { |descendant| heredoc_node?(descendant) }
|
188
|
+
end
|
189
|
+
|
190
|
+
def source_from_node_with_heredoc(node)
|
191
|
+
last_line = -1
|
192
|
+
node.each_descendant do |descendant|
|
193
|
+
next unless descendant.source
|
194
|
+
|
195
|
+
descendant_last_line =
|
196
|
+
if heredoc_node?(descendant)
|
197
|
+
descendant.loc.heredoc_end.line
|
198
|
+
else
|
199
|
+
descendant.last_line
|
200
|
+
end
|
201
|
+
|
202
|
+
last_line = [last_line, descendant_last_line].max
|
203
|
+
end
|
204
|
+
@processed_source[(node.first_line - 1)..(last_line - 1)]
|
205
|
+
end
|
178
206
|
end
|
179
207
|
end
|
180
208
|
end
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
# The token that makes up a disable comment.
|
17
17
|
# The allowed specification for comments after `# rubocop: disable` is
|
18
18
|
# `DepartmentName/CopName` or` all`.
|
19
|
-
DISABLING_COPS_CONTENT_TOKEN = %r{[A-z]+/[A-z]+|all}.freeze
|
19
|
+
DISABLING_COPS_CONTENT_TOKEN = %r{[A-Za-z]+/[A-Za-z]+|all}.freeze
|
20
20
|
|
21
21
|
def on_new_investigation
|
22
22
|
processed_source.comments.each do |comment|
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def contain_unexpected_character_for_department_name?(name)
|
70
|
-
name.match?(%r{[^A-z/, ]})
|
70
|
+
name.match?(%r{[^A-Za-z/, ]})
|
71
71
|
end
|
72
72
|
|
73
73
|
def qualified_legacy_cop_name(cop_name)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to allow certain receivers in a cop.
|
6
|
+
module AllowedReceivers
|
7
|
+
def allowed_receiver?(receiver)
|
8
|
+
receiver_name = receiver_name(receiver)
|
9
|
+
|
10
|
+
allowed_receivers.include?(receiver_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def receiver_name(receiver)
|
14
|
+
if receiver.receiver && !receiver.receiver.const_type?
|
15
|
+
return receiver_name(receiver.receiver)
|
16
|
+
end
|
17
|
+
|
18
|
+
if receiver.send_type?
|
19
|
+
if receiver.receiver
|
20
|
+
"#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
|
21
|
+
else
|
22
|
+
receiver.method_name.to_s
|
23
|
+
end
|
24
|
+
else
|
25
|
+
receiver.source
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def allowed_receivers
|
30
|
+
cop_config.fetch('AllowedReceivers', [])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
def comments_contain_disables?(node, cop_name)
|
26
26
|
disabled_ranges = processed_source.disabled_line_ranges[cop_name]
|
27
27
|
|
28
|
-
return unless disabled_ranges
|
28
|
+
return false unless disabled_ranges
|
29
29
|
|
30
30
|
node_range = node.source_range.line...find_end_line(node)
|
31
31
|
|
@@ -26,11 +26,15 @@ module RuboCop
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def delimiter_string(node)
|
29
|
-
node.source.match(OPENING_DELIMITER)
|
29
|
+
return '' unless (match = node.source.match(OPENING_DELIMITER))
|
30
|
+
|
31
|
+
match.captures[1]
|
30
32
|
end
|
31
33
|
|
32
34
|
def heredoc_type(node)
|
33
|
-
node.source.match(OPENING_DELIMITER)
|
35
|
+
return '' unless (match = node.source.match(OPENING_DELIMITER))
|
36
|
+
|
37
|
+
match.captures[0]
|
34
38
|
end
|
35
39
|
end
|
36
40
|
end
|
@@ -109,7 +109,7 @@ module RuboCop
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def use_block_argument_as_local_variable?(node, last_argument)
|
112
|
-
return if node.body.nil?
|
112
|
+
return false if node.body.nil?
|
113
113
|
|
114
114
|
node.body.each_descendant(:lvar, :lvasgn).any? do |lvar|
|
115
115
|
!lvar.parent.block_pass_type? && lvar.node_parts[0].to_s == last_argument
|
@@ -204,14 +204,14 @@ module RuboCop
|
|
204
204
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
205
205
|
def on_defined?(node)
|
206
206
|
arg = node.arguments.first
|
207
|
-
return unless arg.ivar_type?
|
207
|
+
return false unless arg.ivar_type?
|
208
208
|
|
209
209
|
method_node, method_name = find_definition(node)
|
210
|
-
return unless method_node
|
210
|
+
return false unless method_node
|
211
211
|
|
212
212
|
var_name = arg.children.first
|
213
213
|
defined_memoized?(method_node.body, var_name) do |defined_ivar, return_ivar, ivar_assign|
|
214
|
-
return if matches?(method_name, ivar_assign)
|
214
|
+
return false if matches?(method_name, ivar_assign)
|
215
215
|
|
216
216
|
suggested_var = suggested_var(method_name)
|
217
217
|
msg = format(
|
@@ -20,9 +20,14 @@ module RuboCop
|
|
20
20
|
# # good
|
21
21
|
# fooBar = 1
|
22
22
|
#
|
23
|
+
# @example AllowedIdentifiers: ['fooBar']
|
24
|
+
# # good (with EnforcedStyle: snake_case)
|
25
|
+
# fooBar = 1
|
26
|
+
#
|
23
27
|
# @example AllowedPatterns: ['_v\d+\z']
|
24
|
-
# # good
|
28
|
+
# # good (with EnforcedStyle: camelCase)
|
25
29
|
# :release_v1
|
30
|
+
#
|
26
31
|
class VariableName < Base
|
27
32
|
include AllowedIdentifiers
|
28
33
|
include ConfigurableNaming
|
@@ -92,6 +92,7 @@ module RuboCop
|
|
92
92
|
comment_line?(processed_source[node.first_line - 2])
|
93
93
|
end
|
94
94
|
|
95
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
95
96
|
def groupable_accessor?(node)
|
96
97
|
return true unless (previous_expression = node.left_siblings.last)
|
97
98
|
|
@@ -104,8 +105,11 @@ module RuboCop
|
|
104
105
|
|
105
106
|
return true unless previous_expression.send_type?
|
106
107
|
|
107
|
-
previous_expression.attribute_accessor? ||
|
108
|
+
previous_expression.attribute_accessor? ||
|
109
|
+
previous_expression.access_modifier? ||
|
110
|
+
node.first_line - previous_expression.last_line > 1 # there is a space between nodes
|
108
111
|
end
|
112
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
109
113
|
|
110
114
|
def class_send_elements(class_node)
|
111
115
|
class_def = class_node.body
|
@@ -35,7 +35,7 @@ module RuboCop
|
|
35
35
|
unless contents.empty?
|
36
36
|
corrector.replace(
|
37
37
|
contents,
|
38
|
-
contents.source.gsub(/\A/, '# ').gsub(
|
38
|
+
contents.source.gsub(/\A/, '# ').gsub("\n\n", "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
|
39
39
|
)
|
40
40
|
end
|
41
41
|
corrector.remove(eq_end)
|
@@ -411,7 +411,7 @@ module RuboCop
|
|
411
411
|
end
|
412
412
|
|
413
413
|
def correction_would_break_code?(node)
|
414
|
-
return unless node.keywords?
|
414
|
+
return false unless node.keywords?
|
415
415
|
|
416
416
|
node.send_node.arguments? && !node.send_node.parenthesized?
|
417
417
|
end
|
@@ -433,7 +433,7 @@ module RuboCop
|
|
433
433
|
end
|
434
434
|
|
435
435
|
def return_value_used?(node)
|
436
|
-
return unless node.parent
|
436
|
+
return false unless node.parent
|
437
437
|
|
438
438
|
# If there are parentheses around the block, check if that
|
439
439
|
# is being used.
|
@@ -445,7 +445,7 @@ module RuboCop
|
|
445
445
|
end
|
446
446
|
|
447
447
|
def return_value_of_scope?(node)
|
448
|
-
return unless node.parent
|
448
|
+
return false unless node.parent
|
449
449
|
|
450
450
|
conditional?(node.parent) || array_or_range?(node.parent) ||
|
451
451
|
node.parent.children.last == node
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Enforces the use of `Object#instance_of?` instead of class comparison
|
7
7
|
# for equality.
|
8
|
-
# `==`, `equal?`, and `eql?`
|
8
|
+
# `==`, `equal?`, and `eql?` custom method definitions are allowed by default.
|
9
9
|
# These are customizable with `AllowedMethods` option.
|
10
10
|
#
|
11
11
|
# @example
|
@@ -18,53 +18,31 @@ module RuboCop
|
|
18
18
|
# # good
|
19
19
|
# var.instance_of?(Date)
|
20
20
|
#
|
21
|
-
# @example AllowedMethods: [] (default)
|
21
|
+
# @example AllowedMethods: ['==', 'equal?', 'eql?'] (default)
|
22
22
|
# # good
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# var.class == Date
|
27
|
-
# var.class.equal?(Date)
|
28
|
-
# var.class.eql?(Date)
|
29
|
-
# var.class.name == 'Date'
|
30
|
-
# var.class.to_s == 'Date'
|
31
|
-
# var.class.inspect == 'Date'
|
23
|
+
# def ==(other)
|
24
|
+
# self.class == other.class && name == other.name
|
25
|
+
# end
|
32
26
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# var.class == Date
|
37
|
-
# var.class.name == 'Date'
|
38
|
-
# var.class.to_s == 'Date'
|
39
|
-
# var.class.inspect == 'Date'
|
27
|
+
# def equal?(other)
|
28
|
+
# self.class.equal?(other.class) && name.equal?(other.name)
|
29
|
+
# end
|
40
30
|
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
31
|
+
# def eql?(other)
|
32
|
+
# self.class.eql?(other.class) && name.eql?(other.name)
|
33
|
+
# end
|
44
34
|
#
|
45
35
|
# @example AllowedPatterns: [] (default)
|
46
|
-
# # good
|
47
|
-
# var.instance_of?(Date)
|
48
|
-
#
|
49
36
|
# # bad
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
# var.class.name == 'Date'
|
54
|
-
# var.class.to_s == 'Date'
|
55
|
-
# var.class.inspect == 'Date'
|
37
|
+
# def eq(other)
|
38
|
+
# self.class.eq(other.class) && name.eq(other.name)
|
39
|
+
# end
|
56
40
|
#
|
57
41
|
# @example AllowedPatterns: ['eq']
|
58
42
|
# # good
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
# # bad
|
64
|
-
# var.class == Date
|
65
|
-
# var.class.name == 'Date'
|
66
|
-
# var.class.to_s == 'Date'
|
67
|
-
# var.class.inspect == 'Date'
|
43
|
+
# def eq(other)
|
44
|
+
# self.class.eq(other.class) && name.eq(other.name)
|
45
|
+
# end
|
68
46
|
#
|
69
47
|
class ClassEqualityComparison < Base
|
70
48
|
include RangeHelp
|
@@ -35,7 +35,12 @@ module RuboCop
|
|
35
35
|
# # good
|
36
36
|
# hash.compact!
|
37
37
|
#
|
38
|
+
# @example AllowedReceivers: ['params']
|
39
|
+
# # good
|
40
|
+
# params.reject(&:nil?)
|
41
|
+
#
|
38
42
|
class CollectionCompact < Base
|
43
|
+
include AllowedReceivers
|
39
44
|
include RangeHelp
|
40
45
|
extend AutoCorrector
|
41
46
|
extend TargetRubyVersion
|
@@ -76,6 +81,7 @@ module RuboCop
|
|
76
81
|
|
77
82
|
def on_send(node)
|
78
83
|
return unless (range = offense_range(node))
|
84
|
+
return if allowed_receiver?(node.receiver)
|
79
85
|
if (target_ruby_version <= 3.0 || node.method?(:delete_if)) && to_enum_method?(node)
|
80
86
|
return
|
81
87
|
end
|
@@ -361,7 +361,7 @@ module RuboCop
|
|
361
361
|
end
|
362
362
|
|
363
363
|
def assignment_types_match?(*nodes)
|
364
|
-
return unless assignment_type?(nodes.first)
|
364
|
+
return false unless assignment_type?(nodes.first)
|
365
365
|
|
366
366
|
nodes.map(&:type).uniq.one?
|
367
367
|
end
|
@@ -440,6 +440,8 @@ module RuboCop
|
|
440
440
|
module ConditionalCorrectorHelper
|
441
441
|
def remove_whitespace_in_branches(corrector, branch, condition, column)
|
442
442
|
branch.each_node do |child|
|
443
|
+
next if child.source_range.nil?
|
444
|
+
|
443
445
|
white_space = white_space_range(child, column)
|
444
446
|
corrector.remove(white_space) if white_space.source.strip.empty?
|
445
447
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for places where the
|
6
|
+
# Checks for places where the `#\_\_dir\_\_` method can replace more
|
7
7
|
# complex constructs to retrieve a canonicalized absolute path to the
|
8
8
|
# current file.
|
9
9
|
#
|
@@ -19,18 +19,16 @@ module RuboCop
|
|
19
19
|
extend AutoCorrector
|
20
20
|
extend TargetRubyVersion
|
21
21
|
|
22
|
-
MSG = 'Use
|
23
|
-
RESTRICT_ON_SEND = %i[== > empty? none?].freeze
|
22
|
+
MSG = 'Use `%<replacement>s` instead.'
|
23
|
+
RESTRICT_ON_SEND = %i[== != > empty? none?].freeze
|
24
24
|
|
25
25
|
minimum_target_ruby_version 2.4
|
26
26
|
|
27
27
|
# @!method offensive?(node)
|
28
28
|
def_node_matcher :offensive?, <<~PATTERN
|
29
29
|
{
|
30
|
-
(send (send (send $(const {nil? cbase} :Dir) :entries $_) :size) {:== :>} (int 2))
|
31
|
-
(send (send (send $(const {nil? cbase} :Dir) :children $_) :size) {:== :>} (int 0))
|
32
|
-
(send (send (send (send $(const {nil? cbase} :Dir) :entries $_) :size) :!) {:== :>} (int 2))
|
33
|
-
(send (send (send (send $(const {nil? cbase} :Dir) :children $_) :size) :!) {:== :>} (int 0))
|
30
|
+
(send (send (send $(const {nil? cbase} :Dir) :entries $_) :size) {:== :!= :>} (int 2))
|
31
|
+
(send (send (send $(const {nil? cbase} :Dir) :children $_) :size) {:== :!= :>} (int 0))
|
34
32
|
(send (send $(const {nil? cbase} :Dir) :children $_) :empty?)
|
35
33
|
(send (send $(const {nil? cbase} :Dir) :each_child $_) :none?)
|
36
34
|
}
|
@@ -38,10 +36,9 @@ module RuboCop
|
|
38
36
|
|
39
37
|
def on_send(node)
|
40
38
|
offensive?(node) do |const_node, arg_node|
|
41
|
-
|
42
|
-
|
43
|
-
corrector.replace(node,
|
44
|
-
"#{bang(node)}#{const_node.source}.empty?(#{arg_node.source})")
|
39
|
+
replacement = "#{bang(node)}#{const_node.source}.empty?(#{arg_node.source})"
|
40
|
+
add_offense(node, message: format(MSG, replacement: replacement)) do |corrector|
|
41
|
+
corrector.replace(node, replacement)
|
45
42
|
end
|
46
43
|
end
|
47
44
|
end
|
@@ -49,10 +46,7 @@ module RuboCop
|
|
49
46
|
private
|
50
47
|
|
51
48
|
def bang(node)
|
52
|
-
if
|
53
|
-
(node.method?(:>) && !node.child_nodes.first.method?(:!))
|
54
|
-
'!'
|
55
|
-
end
|
49
|
+
'!' if %i[!= >].include? node.method_name
|
56
50
|
end
|
57
51
|
end
|
58
52
|
end
|
@@ -108,7 +108,7 @@ module RuboCop
|
|
108
108
|
comments = heredoc_comment_blocks(arg_node.loc.heredoc_body.line_span)
|
109
109
|
.concat(preceding_comment_blocks(arg_node.parent))
|
110
110
|
|
111
|
-
return if comments.none?
|
111
|
+
return false if comments.none?
|
112
112
|
|
113
113
|
regexp = comment_regexp(arg_node)
|
114
114
|
comments.any?(regexp) || regexp.match?(comments.join)
|
@@ -4,12 +4,12 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# Ensures that eval methods (`eval`, `instance_eval`, `class_eval`
|
7
|
-
# and `module_eval`) are given filename and line number values (`
|
8
|
-
# and `
|
7
|
+
# and `module_eval`) are given filename and line number values (`\_\_FILE\_\_`
|
8
|
+
# and `\_\_LINE\_\_`). This data is used to ensure that any errors raised
|
9
9
|
# within the evaluated code will be given the correct identification
|
10
10
|
# in a backtrace.
|
11
11
|
#
|
12
|
-
# The cop also checks that the line number given relative to `
|
12
|
+
# The cop also checks that the line number given relative to `\_\_LINE\_\_` is
|
13
13
|
# correct.
|
14
14
|
#
|
15
15
|
# This cop will autocorrect incorrect or missing filename and line number
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
extend AutoCorrector
|
58
58
|
|
59
59
|
MSG = 'Pass `__FILE__` and `__LINE__` to `%<method_name>s`.'
|
60
|
-
MSG_EVAL = 'Pass a binding, `__FILE__
|
60
|
+
MSG_EVAL = 'Pass a binding, `__FILE__`, and `__LINE__` to `eval`.'
|
61
61
|
MSG_INCORRECT_FILE = 'Incorrect file for `%<method_name>s`; ' \
|
62
62
|
'use `%<expected>s` instead of `%<actual>s`.'
|
63
63
|
MSG_INCORRECT_LINE = 'Incorrect line number for `%<method_name>s`; ' \
|
@@ -41,8 +41,7 @@ module RuboCop
|
|
41
41
|
return unless (regexp = exact_regexp_match(node))
|
42
42
|
|
43
43
|
parsed_regexp = Regexp::Parser.parse(regexp)
|
44
|
-
|
45
|
-
return unless tokens[0] == :bos && tokens[1] == :literal && tokens[2] == :eos
|
44
|
+
return unless exact_match_pattern?(parsed_regexp)
|
46
45
|
|
47
46
|
prefer = "#{node.receiver.source} #{new_method(node)} '#{parsed_regexp[1].text}'"
|
48
47
|
|
@@ -53,6 +52,13 @@ module RuboCop
|
|
53
52
|
|
54
53
|
private
|
55
54
|
|
55
|
+
def exact_match_pattern?(parsed_regexp)
|
56
|
+
tokens = parsed_regexp.map(&:token)
|
57
|
+
return false unless tokens[0] == :bos && tokens[1] == :literal && tokens[2] == :eos
|
58
|
+
|
59
|
+
!parsed_regexp[1].quantifier
|
60
|
+
end
|
61
|
+
|
56
62
|
def new_method(node)
|
57
63
|
node.method?(:!~) ? '!=' : '=='
|
58
64
|
end
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
63
63
|
|
64
64
|
# @!method block_read?(node)
|
65
65
|
def_node_matcher :block_read?, <<~PATTERN
|
66
|
-
(block _ (args (arg
|
66
|
+
(block _ (args (arg _name)) (send (lvar _name) :read))
|
67
67
|
PATTERN
|
68
68
|
|
69
69
|
def on_send(node)
|
@@ -100,7 +100,7 @@ module RuboCop
|
|
100
100
|
def file_open_read?(node)
|
101
101
|
return true if send_read?(node)
|
102
102
|
|
103
|
-
block_read?(node)
|
103
|
+
block_read?(node)
|
104
104
|
end
|
105
105
|
|
106
106
|
def read_method(mode)
|
@@ -28,6 +28,7 @@ module RuboCop
|
|
28
28
|
# execute(sql).keys.each { |v| p v }
|
29
29
|
# execute(sql).values.each { |v| p v }
|
30
30
|
class HashEachMethods < Base
|
31
|
+
include AllowedReceivers
|
31
32
|
include Lint::UnusedArgument
|
32
33
|
extend AutoCorrector
|
33
34
|
|
@@ -116,28 +117,6 @@ module RuboCop
|
|
116
117
|
def kv_range(outer_node)
|
117
118
|
outer_node.receiver.loc.selector.join(outer_node.loc.selector)
|
118
119
|
end
|
119
|
-
|
120
|
-
def allowed_receiver?(receiver)
|
121
|
-
receiver_name = receiver_name(receiver)
|
122
|
-
|
123
|
-
allowed_receivers.include?(receiver_name)
|
124
|
-
end
|
125
|
-
|
126
|
-
def receiver_name(receiver)
|
127
|
-
if receiver.send_type?
|
128
|
-
if receiver.receiver
|
129
|
-
"#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
|
130
|
-
else
|
131
|
-
receiver.method_name.to_s
|
132
|
-
end
|
133
|
-
else
|
134
|
-
receiver.source
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def allowed_receivers
|
139
|
-
cop_config.fetch('AllowedReceivers', [])
|
140
|
-
end
|
141
120
|
end
|
142
121
|
end
|
143
122
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Looks for uses of
|
7
|
-
#
|
6
|
+
# Looks for uses of `\_.each_with_object({}) {...}`,
|
7
|
+
# `\_.map {...}.to_h`, and `Hash[\_.map {...}]` that are actually just
|
8
8
|
# transforming the keys of a hash, and tries to use a simpler & faster
|
9
9
|
# call to `transform_keys` instead.
|
10
10
|
# It should only be enabled on Ruby version 2.5 or newer.
|