rubocop 1.32.0 → 1.37.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 +2 -2
- data/config/default.yml +104 -16
- data/config/obsoletion.yml +23 -1
- data/lib/rubocop/arguments_env.rb +17 -0
- data/lib/rubocop/arguments_file.rb +17 -0
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
- data/lib/rubocop/cli/command/execute_runner.rb +7 -7
- data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/config_finder.rb +68 -0
- data/lib/rubocop/config_loader.rb +12 -40
- data/lib/rubocop/config_loader_resolver.rb +1 -5
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
- data/lib/rubocop/config_obsoletion.rb +7 -2
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
- data/lib/rubocop/cop/generator.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +16 -12
- data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
- data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +6 -2
- data/lib/rubocop/cop/layout/line_length.rb +4 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +13 -9
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +25 -9
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +28 -3
- data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
- data/lib/rubocop/cop/legacy/corrector.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
- data/lib/rubocop/cop/lint/debugger.rb +26 -16
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +11 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +25 -6
- data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_class.rb +3 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +107 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +50 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -5
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +29 -9
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
- data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
- data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
- data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -10
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -3
- data/lib/rubocop/cop/lint/unreachable_loop.rb +9 -3
- data/lib/rubocop/cop/lint/unused_method_argument.rb +4 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +8 -6
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +2 -0
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
- data/lib/rubocop/cop/metrics/block_length.rb +6 -7
- data/lib/rubocop/cop/metrics/method_length.rb +8 -8
- data/lib/rubocop/cop/mixin/allowed_methods.rb +20 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +17 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +17 -1
- data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +82 -4
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -6
- data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/range_help.rb +4 -5
- data/lib/rubocop/cop/mixin/rescue_node.rb +3 -1
- data/lib/rubocop/cop/mixin/surrounding_space.rb +6 -5
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +97 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +7 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
- data/lib/rubocop/cop/style/case_equality.rb +40 -10
- data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
- data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
- data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
- data/lib/rubocop/cop/style/collection_compact.rb +6 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
- data/lib/rubocop/cop/style/double_negation.rb +2 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +41 -6
- data/lib/rubocop/cop/style/each_with_object.rb +39 -8
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +4 -0
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string_token.rb +21 -8
- data/lib/rubocop/cop/style/guard_clause.rb +27 -16
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
- data/lib/rubocop/cop/style/hash_except.rb +0 -4
- data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
- data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +15 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -1
- data/lib/rubocop/cop/style/next.rb +3 -5
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
- data/lib/rubocop/cop/style/object_then.rb +2 -0
- data/lib/rubocop/cop/style/operator_method_call.rb +39 -0
- data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
- data/lib/rubocop/cop/style/proc.rb +4 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +3 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +24 -6
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +19 -22
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +8 -1
- data/lib/rubocop/cop/style/redundant_self.rb +2 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
- data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
- data/lib/rubocop/cop/style/redundant_string_escape.rb +173 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
- data/lib/rubocop/cop/style/static_class.rb +32 -1
- data/lib/rubocop/cop/style/symbol_array.rb +3 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +38 -12
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
- data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +3 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/ext/range.rb +15 -0
- data/lib/rubocop/feature_loader.rb +94 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +9 -3
- data/lib/rubocop/formatter/html_formatter.rb +3 -3
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +1 -1
- data/lib/rubocop/options.rb +13 -13
- data/lib/rubocop/result_cache.rb +22 -20
- data/lib/rubocop/rspec/shared_contexts.rb +13 -1
- data/lib/rubocop/runner.rb +4 -0
- data/lib/rubocop/server/cache.rb +41 -2
- data/lib/rubocop/server/cli.rb +26 -2
- data/lib/rubocop/server/client_command/exec.rb +5 -0
- data/lib/rubocop/server/core.rb +2 -1
- data/lib/rubocop/server/socket_reader.rb +5 -1
- data/lib/rubocop/server.rb +1 -1
- data/lib/rubocop/version.rb +8 -2
- data/lib/rubocop.rb +8 -3
- metadata +20 -9
- data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -90,6 +90,8 @@ module RuboCop
|
|
90
90
|
check_members(end_loc, [node.body])
|
91
91
|
end
|
92
92
|
|
93
|
+
alias on_numblock on_block
|
94
|
+
|
93
95
|
def on_class(node)
|
94
96
|
base = node.loc.keyword
|
95
97
|
return if same_line?(base, node.body)
|
@@ -146,7 +148,9 @@ module RuboCop
|
|
146
148
|
check_indentation(in_pattern_node.loc.keyword, in_pattern_node.body)
|
147
149
|
end
|
148
150
|
|
149
|
-
|
151
|
+
else_branch = case_match.else_branch&.empty_else_type? ? nil : case_match.else_branch
|
152
|
+
|
153
|
+
check_indentation(case_match.in_pattern_branches.last.loc.keyword, else_branch)
|
150
154
|
end
|
151
155
|
|
152
156
|
def on_if(node, base = node)
|
@@ -339,7 +343,7 @@ module RuboCop
|
|
339
343
|
end
|
340
344
|
|
341
345
|
def skip_check?(base_loc, body_node)
|
342
|
-
return true if
|
346
|
+
return true if allowed_line?(base_loc)
|
343
347
|
return true unless body_node
|
344
348
|
|
345
349
|
# Don't check if expression is on same line as "then" keyword, etc.
|
@@ -22,6 +22,7 @@ module RuboCop
|
|
22
22
|
# (Many of these are enabled by default.)
|
23
23
|
#
|
24
24
|
# * ArgumentAlignment
|
25
|
+
# * ArrayAlignment
|
25
26
|
# * BlockAlignment
|
26
27
|
# * BlockDelimiters
|
27
28
|
# * BlockEndNewline
|
@@ -74,6 +75,8 @@ module RuboCop
|
|
74
75
|
check_for_breakable_block(node)
|
75
76
|
end
|
76
77
|
|
78
|
+
alias on_numblock on_block
|
79
|
+
|
77
80
|
def on_potential_breakable_node(node)
|
78
81
|
check_for_breakable_node(node)
|
79
82
|
end
|
@@ -131,7 +134,7 @@ module RuboCop
|
|
131
134
|
if block_node.arguments? && !block_node.lambda?
|
132
135
|
block_node.arguments.loc.end
|
133
136
|
else
|
134
|
-
block_node.loc.begin
|
137
|
+
block_node.braces? ? block_node.loc.begin : block_node.loc.begin.adjust(begin_pos: 1)
|
135
138
|
end
|
136
139
|
end
|
137
140
|
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
return if node.send_type? && node.loc.operator&.source != '='
|
74
74
|
return unless rhs
|
75
75
|
return unless supported_types.include?(rhs.type)
|
76
|
-
return if rhs.
|
76
|
+
return if rhs.single_line?
|
77
77
|
|
78
78
|
check_by_enforced_style(node, rhs)
|
79
79
|
end
|
@@ -101,7 +101,7 @@ module RuboCop
|
|
101
101
|
!comment_within?(node) &&
|
102
102
|
node.each_descendant(:if, :case, :kwbegin, :def).none? &&
|
103
103
|
node.each_descendant(:dstr, :str).none?(&:heredoc?) &&
|
104
|
-
node.each_descendant(:begin).none? { |b| b.
|
104
|
+
node.each_descendant(:begin).none? { |b| !b.single_line? }
|
105
105
|
end
|
106
106
|
|
107
107
|
def convertible_block?(node)
|
@@ -169,19 +169,22 @@ module RuboCop
|
|
169
169
|
|
170
170
|
def qualifies_for_compact?(node, token, side: :right)
|
171
171
|
if side == :right
|
172
|
-
multi_dimensional_array?(node, token) &&
|
172
|
+
multi_dimensional_array?(node, token) && token.space_before?
|
173
173
|
else
|
174
|
-
multi_dimensional_array?(node, token, side: :left) &&
|
175
|
-
!next_to_bracket?(token, side: :left)
|
174
|
+
multi_dimensional_array?(node, token, side: :left) && token.space_after?
|
176
175
|
end
|
177
176
|
end
|
178
177
|
|
179
178
|
def multi_dimensional_array?(node, token, side: :right)
|
180
|
-
|
179
|
+
offset = side == :right ? -1 : +1
|
180
|
+
i = index_for(node, token) + offset
|
181
|
+
# TODO: change this type check once
|
182
|
+
# https://github.com/rubocop/rubocop-ast/pull/240 is merged
|
183
|
+
i += offset while processed_source.tokens_within(node)[i].new_line?
|
181
184
|
if side == :right
|
182
|
-
processed_source.tokens_within(node)[i
|
185
|
+
processed_source.tokens_within(node)[i].right_bracket?
|
183
186
|
else
|
184
|
-
processed_source.tokens_within(node)[i
|
187
|
+
processed_source.tokens_within(node)[i].left_array_bracket?
|
185
188
|
end
|
186
189
|
end
|
187
190
|
|
@@ -200,12 +203,13 @@ module RuboCop
|
|
200
203
|
end
|
201
204
|
|
202
205
|
def compact_corrections(corrector, node, left, right)
|
203
|
-
if
|
206
|
+
if multi_dimensional_array?(node, left, side: :left)
|
204
207
|
compact(corrector, left, :right)
|
205
208
|
elsif !left.space_after?
|
206
209
|
corrector.insert_after(left.pos, ' ')
|
207
210
|
end
|
208
|
-
|
211
|
+
|
212
|
+
if multi_dimensional_array?(node, right)
|
209
213
|
compact(corrector, right, :left)
|
210
214
|
elsif !right.space_before?
|
211
215
|
corrector.insert_before(right.pos, ' ')
|
@@ -213,7 +217,7 @@ module RuboCop
|
|
213
217
|
end
|
214
218
|
|
215
219
|
def compact(corrector, bracket, side)
|
216
|
-
range = side_space_range(range: bracket.pos, side: side)
|
220
|
+
range = side_space_range(range: bracket.pos, side: side, include_newlines: true)
|
217
221
|
corrector.remove(range)
|
218
222
|
end
|
219
223
|
end
|
@@ -131,7 +131,7 @@ module RuboCop
|
|
131
131
|
args_delimiter = node.arguments.loc.begin if node.block_type? # Can be ( | or nil.
|
132
132
|
|
133
133
|
check_left_brace(inner, node.loc.begin, args_delimiter)
|
134
|
-
check_right_brace(inner, node.loc.begin, node.loc.end, node.single_line?)
|
134
|
+
check_right_brace(node, inner, node.loc.begin, node.loc.end, node.single_line?)
|
135
135
|
end
|
136
136
|
|
137
137
|
def check_left_brace(inner, left_brace, args_delimiter)
|
@@ -142,14 +142,15 @@ module RuboCop
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
def check_right_brace(inner, left_brace, right_brace, single_line)
|
145
|
+
def check_right_brace(node, inner, left_brace, right_brace, single_line)
|
146
146
|
if single_line && /\S$/.match?(inner)
|
147
147
|
no_space(right_brace.begin_pos, right_brace.end_pos, 'Space missing inside }.')
|
148
148
|
else
|
149
|
+
column = node.loc.expression.column
|
149
150
|
return if multiline_block?(left_brace, right_brace) &&
|
150
|
-
aligned_braces?(
|
151
|
+
aligned_braces?(inner, right_brace, column)
|
151
152
|
|
152
|
-
space_inside_right_brace(right_brace)
|
153
|
+
space_inside_right_brace(inner, right_brace, column)
|
153
154
|
end
|
154
155
|
end
|
155
156
|
|
@@ -157,8 +158,12 @@ module RuboCop
|
|
157
158
|
left_brace.first_line != right_brace.first_line
|
158
159
|
end
|
159
160
|
|
160
|
-
def aligned_braces?(
|
161
|
-
|
161
|
+
def aligned_braces?(inner, right_brace, column)
|
162
|
+
column == right_brace.column || column == inner_last_space_count(inner)
|
163
|
+
end
|
164
|
+
|
165
|
+
def inner_last_space_count(inner)
|
166
|
+
inner.split("\n").last.count(' ')
|
162
167
|
end
|
163
168
|
|
164
169
|
def no_space_inside_left_brace(left_brace, args_delimiter)
|
@@ -197,10 +202,21 @@ module RuboCop
|
|
197
202
|
args_delimiter&.is?('|')
|
198
203
|
end
|
199
204
|
|
200
|
-
def space_inside_right_brace(right_brace)
|
205
|
+
def space_inside_right_brace(inner, right_brace, column)
|
201
206
|
brace_with_space = range_with_surrounding_space(right_brace, side: :left)
|
202
|
-
|
203
|
-
|
207
|
+
begin_pos = brace_with_space.begin_pos
|
208
|
+
end_pos = brace_with_space.end_pos - 1
|
209
|
+
|
210
|
+
if brace_with_space.source.match?(/\R/)
|
211
|
+
begin_pos = end_pos - (right_brace.column - column)
|
212
|
+
end
|
213
|
+
|
214
|
+
if inner.end_with?(']')
|
215
|
+
end_pos -= 1
|
216
|
+
begin_pos = end_pos - (inner_last_space_count(inner) - column)
|
217
|
+
end
|
218
|
+
|
219
|
+
space(begin_pos, end_pos, 'Space inside } detected.')
|
204
220
|
end
|
205
221
|
|
206
222
|
def no_space(begin_pos, end_pos, msg)
|
@@ -46,10 +46,13 @@ module RuboCop
|
|
46
46
|
# # bad
|
47
47
|
# foo = { }
|
48
48
|
# bar = { }
|
49
|
+
# baz = {
|
50
|
+
# }
|
49
51
|
#
|
50
52
|
# # good
|
51
53
|
# foo = {}
|
52
54
|
# bar = {}
|
55
|
+
# baz = {}
|
53
56
|
#
|
54
57
|
# @example EnforcedStyleForEmptyBraces: space
|
55
58
|
# # The `space` EnforcedStyleForEmptyBraces style enforces that
|
@@ -60,8 +63,9 @@ module RuboCop
|
|
60
63
|
#
|
61
64
|
# # good
|
62
65
|
# foo = { }
|
63
|
-
# foo = {
|
64
|
-
# foo = {
|
66
|
+
# foo = { }
|
67
|
+
# foo = {
|
68
|
+
# }
|
65
69
|
#
|
66
70
|
class SpaceInsideHashLiteralBraces < Base
|
67
71
|
include SurroundingSpace
|
@@ -77,6 +81,7 @@ module RuboCop
|
|
77
81
|
|
78
82
|
check(tokens[0], tokens[1])
|
79
83
|
check(tokens[-2], tokens[-1]) if tokens.size > 2
|
84
|
+
check_whitespace_only_hash(node) if enforce_no_space_style_for_empty_braces?
|
80
85
|
end
|
81
86
|
|
82
87
|
private
|
@@ -103,7 +108,7 @@ module RuboCop
|
|
103
108
|
if is_same_braces && style == :compact
|
104
109
|
false
|
105
110
|
elsif is_empty_braces
|
106
|
-
|
111
|
+
!enforce_no_space_style_for_empty_braces?
|
107
112
|
else
|
108
113
|
style != :no_space
|
109
114
|
end
|
@@ -175,6 +180,26 @@ module RuboCop
|
|
175
180
|
|
176
181
|
range_between(begin_pos, range.end_pos - 1)
|
177
182
|
end
|
183
|
+
|
184
|
+
def check_whitespace_only_hash(node)
|
185
|
+
range = range_inside_hash(node)
|
186
|
+
return unless range.source.match?(/\A\s+\z/m)
|
187
|
+
|
188
|
+
add_offense(
|
189
|
+
range,
|
190
|
+
message: format(MSG, problem: 'empty hash literal braces detected')
|
191
|
+
) do |corrector|
|
192
|
+
corrector.remove(range)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def range_inside_hash(node)
|
197
|
+
range_between(node.location.begin.end_pos, node.location.end.begin_pos)
|
198
|
+
end
|
199
|
+
|
200
|
+
def enforce_no_space_style_for_empty_braces?
|
201
|
+
cop_config['EnforcedStyleForEmptyBraces'] == 'no_space'
|
202
|
+
end
|
178
203
|
end
|
179
204
|
end
|
180
205
|
end
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Legacy
|
6
6
|
# Legacy support for Corrector#corrections
|
7
|
-
# See https://docs.rubocop.org/rubocop/
|
7
|
+
# See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
|
8
8
|
class CorrectionsProxy
|
9
9
|
def initialize(corrector)
|
10
10
|
@corrector = corrector
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Legacy
|
6
6
|
# Legacy Corrector for v0 API support.
|
7
|
-
# See https://docs.rubocop.org/rubocop/
|
7
|
+
# See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html
|
8
8
|
class Corrector < RuboCop::Cop::Corrector
|
9
9
|
# Support legacy second argument
|
10
10
|
def initialize(source, corr = [])
|
@@ -6,8 +6,8 @@ module RuboCop
|
|
6
6
|
# Checks for ambiguous block association with method
|
7
7
|
# when param passed without parentheses.
|
8
8
|
#
|
9
|
-
# This cop can customize
|
10
|
-
# By default, there are no methods to
|
9
|
+
# This cop can customize allowed methods with `AllowedMethods`.
|
10
|
+
# By default, there are no methods to allowed.
|
11
11
|
#
|
12
12
|
# @example
|
13
13
|
#
|
@@ -30,18 +30,30 @@ module RuboCop
|
|
30
30
|
# # Lambda arguments require no disambiguation
|
31
31
|
# foo = ->(bar) { bar.baz }
|
32
32
|
#
|
33
|
-
# @example
|
33
|
+
# @example AllowedMethods: [] (default)
|
34
34
|
#
|
35
35
|
# # bad
|
36
36
|
# expect { do_something }.to change { object.attribute }
|
37
37
|
#
|
38
|
-
# @example
|
38
|
+
# @example AllowedMethods: [change]
|
39
39
|
#
|
40
40
|
# # good
|
41
41
|
# expect { do_something }.to change { object.attribute }
|
42
42
|
#
|
43
|
+
# @example AllowedPatterns: [] (default)
|
44
|
+
#
|
45
|
+
# # bad
|
46
|
+
# expect { do_something }.to change { object.attribute }
|
47
|
+
#
|
48
|
+
# @example AllowedPatterns: ['change']
|
49
|
+
#
|
50
|
+
# # good
|
51
|
+
# expect { do_something }.to change { object.attribute }
|
52
|
+
# expect { do_something }.to not_change { object.attribute }
|
53
|
+
#
|
43
54
|
class AmbiguousBlockAssociation < Base
|
44
|
-
include
|
55
|
+
include AllowedMethods
|
56
|
+
include AllowedPattern
|
45
57
|
|
46
58
|
MSG = 'Parenthesize the param `%<param>s` to make sure that the ' \
|
47
59
|
'block will be associated with the `%<method>s` method ' \
|
@@ -52,7 +64,7 @@ module RuboCop
|
|
52
64
|
|
53
65
|
return unless ambiguous_block_association?(node)
|
54
66
|
return if node.parenthesized? || node.last_argument.lambda? || node.last_argument.proc? ||
|
55
|
-
|
67
|
+
allowed_method_pattern?(node)
|
56
68
|
|
57
69
|
message = message(node)
|
58
70
|
|
@@ -66,9 +78,10 @@ module RuboCop
|
|
66
78
|
send_node.last_argument.block_type? && !send_node.last_argument.send_node.arguments?
|
67
79
|
end
|
68
80
|
|
69
|
-
def
|
81
|
+
def allowed_method_pattern?(node)
|
70
82
|
node.assignment? || node.operator_method? || node.method?(:[]) ||
|
71
|
-
|
83
|
+
allowed_method?(node.last_argument.method_name) ||
|
84
|
+
matches_allowed_pattern?(node.last_argument.send_node.source)
|
72
85
|
end
|
73
86
|
|
74
87
|
def message(send_node)
|
@@ -15,9 +15,19 @@ module RuboCop
|
|
15
15
|
# [source,yaml]
|
16
16
|
# ----
|
17
17
|
# Lint/Debugger:
|
18
|
-
#
|
18
|
+
# DebuggerMethods:
|
19
|
+
# WebConsole: ~
|
19
20
|
# ----
|
20
21
|
#
|
22
|
+
# You can also add your own methods by adding a new category:
|
23
|
+
#
|
24
|
+
# [source,yaml]
|
25
|
+
# ----
|
26
|
+
# Lint/Debugger:
|
27
|
+
# DebuggerMethods:
|
28
|
+
# MyDebugger:
|
29
|
+
# MyDebugger.debug_this
|
30
|
+
# ----
|
21
31
|
#
|
22
32
|
# @example
|
23
33
|
#
|
@@ -57,19 +67,6 @@ module RuboCop
|
|
57
67
|
class Debugger < Base
|
58
68
|
MSG = 'Remove debugger entry point `%<source>s`.'
|
59
69
|
|
60
|
-
# @!method kernel?(node)
|
61
|
-
def_node_matcher :kernel?, <<~PATTERN
|
62
|
-
(const {nil? cbase} :Kernel)
|
63
|
-
PATTERN
|
64
|
-
|
65
|
-
# @!method valid_receiver?(node, arg1)
|
66
|
-
def_node_matcher :valid_receiver?, <<~PATTERN
|
67
|
-
{
|
68
|
-
(const {nil? cbase} %1)
|
69
|
-
(send {nil? #kernel?} %1)
|
70
|
-
}
|
71
|
-
PATTERN
|
72
|
-
|
73
70
|
def on_send(node)
|
74
71
|
return unless debugger_method?(node)
|
75
72
|
|
@@ -91,7 +88,7 @@ module RuboCop
|
|
91
88
|
|
92
89
|
*receiver, method_name = v.split('.')
|
93
90
|
{
|
94
|
-
receiver: receiver.empty? ? nil : receiver.
|
91
|
+
receiver: receiver.empty? ? nil : receiver.map(&:to_sym),
|
95
92
|
method_name: method_name.to_sym
|
96
93
|
}
|
97
94
|
end.compact
|
@@ -105,10 +102,23 @@ module RuboCop
|
|
105
102
|
if method[:receiver].nil?
|
106
103
|
send_node.receiver.nil?
|
107
104
|
else
|
108
|
-
|
105
|
+
method[:receiver] == receiver_chain(send_node)
|
109
106
|
end
|
110
107
|
end
|
111
108
|
end
|
109
|
+
|
110
|
+
def receiver_chain(send_node)
|
111
|
+
receivers = []
|
112
|
+
receiver = send_node.receiver
|
113
|
+
|
114
|
+
while receiver
|
115
|
+
name = receiver.send_type? ? receiver.method_name : receiver.const_name&.to_sym
|
116
|
+
receivers.unshift(name)
|
117
|
+
receiver = receiver.receiver
|
118
|
+
end
|
119
|
+
|
120
|
+
receivers
|
121
|
+
end
|
112
122
|
end
|
113
123
|
end
|
114
124
|
end
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
private
|
67
67
|
|
68
68
|
def delimiter
|
69
|
-
|
69
|
+
CLASS_METHOD_DELIMITER
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -89,7 +89,7 @@ module RuboCop
|
|
89
89
|
private
|
90
90
|
|
91
91
|
def delimiter
|
92
|
-
instance_method? ?
|
92
|
+
instance_method? ? INSTANCE_METHOD_DELIMITER : CLASS_METHOD_DELIMITER
|
93
93
|
end
|
94
94
|
|
95
95
|
def instance_method?
|
@@ -126,8 +126,8 @@ module RuboCop
|
|
126
126
|
|
127
127
|
RESTRICT_ON_SEND = DEPRECATED_METHODS_OBJECT.keys.map(&:method).freeze
|
128
128
|
|
129
|
-
|
130
|
-
|
129
|
+
CLASS_METHOD_DELIMITER = '.'
|
130
|
+
INSTANCE_METHOD_DELIMITER = '#'
|
131
131
|
|
132
132
|
def on_send(node)
|
133
133
|
check(node) do |deprecated|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for duplicated magic comments.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
#
|
12
|
+
# # encoding: ascii
|
13
|
+
# # encoding: ascii
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
#
|
17
|
+
# # encoding: ascii
|
18
|
+
#
|
19
|
+
# # bad
|
20
|
+
#
|
21
|
+
# # frozen_string_literal: true
|
22
|
+
# # frozen_string_literal: true
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
#
|
26
|
+
# # frozen_string_literal: true
|
27
|
+
#
|
28
|
+
class DuplicateMagicComment < Base
|
29
|
+
include FrozenStringLiteral
|
30
|
+
include RangeHelp
|
31
|
+
extend AutoCorrector
|
32
|
+
|
33
|
+
MSG = 'Duplicate magic comment detected.'
|
34
|
+
|
35
|
+
def on_new_investigation
|
36
|
+
return if processed_source.buffer.source.empty?
|
37
|
+
|
38
|
+
magic_comment_lines.each_value do |comment_lines|
|
39
|
+
next if comment_lines.count <= 1
|
40
|
+
|
41
|
+
comment_lines[1..].each do |comment_line|
|
42
|
+
range = processed_source.buffer.line_range(comment_line + 1)
|
43
|
+
|
44
|
+
register_offense(range)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def magic_comment_lines
|
52
|
+
comment_lines = { encoding_magic_comments: [], frozen_string_literal_magic_comments: [] }
|
53
|
+
|
54
|
+
leading_magic_comments.each.with_index do |magic_comment, index|
|
55
|
+
if magic_comment.encoding_specified?
|
56
|
+
comment_lines[:encoding_magic_comments] << index
|
57
|
+
elsif magic_comment.frozen_string_literal_specified?
|
58
|
+
comment_lines[:frozen_string_literal_magic_comments] << index
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
comment_lines
|
63
|
+
end
|
64
|
+
|
65
|
+
def register_offense(range)
|
66
|
+
add_offense(range) do |corrector|
|
67
|
+
corrector.remove(range_by_whole_lines(range, include_final_newline: true))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -133,7 +133,7 @@ module RuboCop
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def found_instance_method(node, name)
|
136
|
-
return unless (scope = node.parent_module_name)
|
136
|
+
return found_sclass_method(node, name) unless (scope = node.parent_module_name)
|
137
137
|
|
138
138
|
# Humanize the scope
|
139
139
|
scope = scope.sub(
|
@@ -145,6 +145,16 @@ module RuboCop
|
|
145
145
|
found_method(node, "#{scope}#{name}")
|
146
146
|
end
|
147
147
|
|
148
|
+
def found_sclass_method(node, name)
|
149
|
+
singleton_ancestor = node.each_ancestor.find(&:sclass_type?)
|
150
|
+
return unless singleton_ancestor
|
151
|
+
|
152
|
+
singleton_receiver_node = singleton_ancestor.children[0]
|
153
|
+
return unless singleton_receiver_node.send_type?
|
154
|
+
|
155
|
+
found_method(node, "#{singleton_receiver_node.method_name}.#{name}")
|
156
|
+
end
|
157
|
+
|
148
158
|
def found_method(node, method_name)
|
149
159
|
if @definitions.key?(method_name)
|
150
160
|
loc = case node.type
|
@@ -32,26 +32,40 @@ module RuboCop
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
35
36
|
def each_repeated_character_class_element_loc(node)
|
36
37
|
node.parsed_tree&.each_expression do |expr|
|
37
|
-
next if expr
|
38
|
+
next if skip_expression?(expr)
|
38
39
|
|
39
40
|
seen = Set.new
|
41
|
+
enum = expr.expressions.to_enum
|
42
|
+
expression_count = expr.expressions.count
|
40
43
|
|
41
|
-
|
42
|
-
|
44
|
+
expression_count.times do |current_number|
|
45
|
+
current_child = enum.next
|
46
|
+
next if within_interpolation?(node, current_child)
|
43
47
|
|
44
|
-
|
48
|
+
current_child_source = current_child.to_s
|
49
|
+
next_child = enum.peek if current_number + 1 < expression_count
|
45
50
|
|
46
|
-
|
51
|
+
if seen.include?(current_child_source)
|
52
|
+
next if start_with_escaped_zero_number?(current_child_source, next_child.to_s)
|
47
53
|
|
48
|
-
|
54
|
+
yield current_child.expression
|
55
|
+
end
|
56
|
+
|
57
|
+
seen << current_child_source
|
49
58
|
end
|
50
59
|
end
|
51
60
|
end
|
61
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
52
62
|
|
53
63
|
private
|
54
64
|
|
65
|
+
def skip_expression?(expr)
|
66
|
+
expr.type != :set || expr.token == :intersection
|
67
|
+
end
|
68
|
+
|
55
69
|
# Since we blank interpolations with a space for every char of the interpolation, we would
|
56
70
|
# mark every space (except the first) as duplicate if we do not skip regexp_parser nodes
|
57
71
|
# that are within an interpolation.
|
@@ -61,6 +75,11 @@ module RuboCop
|
|
61
75
|
interpolation_locs(node).any? { |il| il.overlaps?(parse_tree_child_loc) }
|
62
76
|
end
|
63
77
|
|
78
|
+
def start_with_escaped_zero_number?(current_child, next_child)
|
79
|
+
# Represents escaped code from `"\00"` (`"\u0000"`) to `"\07"` (`"\a"`).
|
80
|
+
current_child == '\\0' && next_child.match?(/[0-7]/)
|
81
|
+
end
|
82
|
+
|
64
83
|
def interpolation_locs(node)
|
65
84
|
@interpolation_locs ||= {}
|
66
85
|
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
63
63
|
class EmptyBlock < Base
|
64
64
|
MSG = 'Empty block detected.'
|
65
65
|
|
66
|
-
def on_block(node)
|
66
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
67
67
|
return if node.body
|
68
68
|
return if allow_empty_lambdas? && lambda_or_proc?(node)
|
69
69
|
return if cop_config['AllowComments'] && allow_comment?(node)
|