rubocop 1.75.8 → 1.82.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 +20 -16
- data/config/default.yml +142 -33
- data/config/obsoletion.yml +10 -3
- data/exe/rubocop +1 -8
- data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
- data/lib/rubocop/cli.rb +20 -4
- data/lib/rubocop/comment_config.rb +62 -17
- data/lib/rubocop/config_loader.rb +6 -40
- data/lib/rubocop/config_loader_resolver.rb +7 -6
- data/lib/rubocop/config_store.rb +5 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +8 -4
- data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -7
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +0 -22
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
- data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +10 -5
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +4 -1
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +30 -12
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +2 -5
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -4
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +12 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +43 -10
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +7 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +8 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +2 -9
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -2
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
- data/lib/rubocop/cop/lint/debugger.rb +0 -2
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +25 -4
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +4 -4
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/literal_as_condition.rb +38 -28
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +17 -8
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -1
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +4 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +4 -4
- data/lib/rubocop/cop/lint/self_assignment.rb +39 -5
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +5 -3
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +29 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +44 -16
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
- data/lib/rubocop/cop/lint/useless_or.rb +111 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +3 -3
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/lint/void.rb +7 -0
- data/lib/rubocop/cop/message_annotator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -4
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -1
- data/lib/rubocop/cop/mixin/line_length_help.rb +45 -10
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
- data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -5
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/method_name.rb +129 -13
- data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +4 -4
- data/lib/rubocop/cop/security/eval.rb +2 -1
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +13 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +11 -17
- data/lib/rubocop/cop/style/array_intersect.rb +99 -35
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -2
- data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/case_equality.rb +11 -13
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +12 -16
- data/lib/rubocop/cop/style/constant_visibility.rb +17 -12
- data/lib/rubocop/cop/style/dig_chain.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +0 -6
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/endless_method.rb +15 -2
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -2
- data/lib/rubocop/cop/style/fetch_env_var.rb +32 -6
- data/lib/rubocop/cop/style/float_division.rb +15 -1
- data/lib/rubocop/cop/style/guard_clause.rb +0 -11
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -9
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
- data/lib/rubocop/cop/style/it_assignment.rb +69 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +36 -15
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -3
- data/lib/rubocop/cop/style/map_to_set.rb +1 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -6
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +12 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +33 -4
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- data/lib/rubocop/cop/style/module_member_existence_check.rb +74 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -4
- data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
- data/lib/rubocop/cop/style/one_line_conditional.rb +17 -9
- data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +34 -22
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +34 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_format.rb +26 -5
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +55 -16
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/redundant_self.rb +8 -5
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/safe_navigation.rb +44 -12
- data/lib/rubocop/cop/style/semicolon.rb +23 -7
- data/lib/rubocop/cop/style/single_line_methods.rb +7 -4
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +40 -3
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
- data/lib/rubocop/cop/style/super_arguments.rb +2 -2
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/util.rb +2 -3
- data/lib/rubocop/cop/utils/format_string.rb +10 -0
- data/lib/rubocop/cop/variable_force/variable.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +25 -8
- data/lib/rubocop/cops_documentation_generator.rb +5 -4
- data/lib/rubocop/directive_comment.rb +46 -3
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -5
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -0
- data/lib/rubocop/lsp/diagnostic.rb +14 -18
- data/lib/rubocop/lsp/routes.rb +35 -6
- data/lib/rubocop/lsp/stdin_runner.rb +0 -16
- data/lib/rubocop/magic_comment.rb +20 -0
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +7 -8
- data/lib/rubocop/result_cache.rb +51 -38
- data/lib/rubocop/rspec/expect_offense.rb +9 -3
- data/lib/rubocop/rspec/shared_contexts.rb +2 -2
- data/lib/rubocop/rspec/support.rb +1 -1
- data/lib/rubocop/runner.rb +10 -4
- data/lib/rubocop/server/cache.rb +4 -2
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/target_finder.rb +9 -9
- data/lib/rubocop/target_ruby.rb +11 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +13 -1
- data/lib/ruby_lsp/rubocop/addon.rb +25 -10
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
- metadata +20 -8
|
@@ -24,8 +24,6 @@ module RuboCop
|
|
|
24
24
|
|
|
25
25
|
MSG_REPEATED_ELEMENT = 'Duplicate element inside regexp character class'
|
|
26
26
|
|
|
27
|
-
OCTAL_DIGITS_AFTER_ESCAPE = 2
|
|
28
|
-
|
|
29
27
|
def on_regexp(node)
|
|
30
28
|
each_repeated_character_class_element_loc(node) do |loc|
|
|
31
29
|
add_offense(loc, message: MSG_REPEATED_ELEMENT) do |corrector|
|
|
@@ -40,9 +38,9 @@ module RuboCop
|
|
|
40
38
|
|
|
41
39
|
seen = Set.new
|
|
42
40
|
group_expressions(node, expr.expressions) do |group|
|
|
43
|
-
group_source = group.
|
|
41
|
+
group_source = group.to_s
|
|
44
42
|
|
|
45
|
-
yield
|
|
43
|
+
yield group.expression if seen.include?(group_source)
|
|
46
44
|
|
|
47
45
|
seen << group_source
|
|
48
46
|
end
|
|
@@ -52,40 +50,13 @@ module RuboCop
|
|
|
52
50
|
private
|
|
53
51
|
|
|
54
52
|
def group_expressions(node, expressions)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
until expressions.empty?
|
|
59
|
-
# With we may need to compose a group of multiple expressions.
|
|
60
|
-
group = [expressions.shift]
|
|
61
|
-
next if within_interpolation?(node, group.first)
|
|
62
|
-
|
|
63
|
-
# With regexp_parser < 2.7 escaped octal sequences may be up to 3
|
|
64
|
-
# separate expressions ("\\0", "0", "1").
|
|
65
|
-
pop_octal_digits(group, expressions) if escaped_octal?(group.first.to_s)
|
|
66
|
-
|
|
67
|
-
yield(group)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def pop_octal_digits(current_child, expressions)
|
|
72
|
-
OCTAL_DIGITS_AFTER_ESCAPE.times do
|
|
73
|
-
next_child = expressions.first
|
|
74
|
-
break unless octal?(next_child.to_s)
|
|
53
|
+
expressions.each do |expression|
|
|
54
|
+
next if within_interpolation?(node, expression)
|
|
75
55
|
|
|
76
|
-
|
|
56
|
+
yield(expression)
|
|
77
57
|
end
|
|
78
58
|
end
|
|
79
59
|
|
|
80
|
-
def source_range(children)
|
|
81
|
-
return children.first.expression if children.size == 1
|
|
82
|
-
|
|
83
|
-
range_between(
|
|
84
|
-
children.first.expression.begin_pos,
|
|
85
|
-
children.last.expression.begin_pos + children.last.to_s.length
|
|
86
|
-
)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
60
|
def skip_expression?(expr)
|
|
90
61
|
expr.type != :set || expr.token == :intersection
|
|
91
62
|
end
|
|
@@ -99,14 +70,6 @@ module RuboCop
|
|
|
99
70
|
interpolation_locs(node).any? { |il| il.overlaps?(parse_tree_child_loc) }
|
|
100
71
|
end
|
|
101
72
|
|
|
102
|
-
def escaped_octal?(string)
|
|
103
|
-
string.length == 2 && string[0] == '\\' && octal?(string[1])
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def octal?(char)
|
|
107
|
-
('0'..'7').cover?(char)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
73
|
def interpolation_locs(node)
|
|
111
74
|
@interpolation_locs ||= {}
|
|
112
75
|
|
|
@@ -38,6 +38,24 @@ module RuboCop
|
|
|
38
38
|
# elsif do_this
|
|
39
39
|
# do_that
|
|
40
40
|
# end
|
|
41
|
+
#
|
|
42
|
+
# # bad
|
|
43
|
+
#
|
|
44
|
+
# # For single-line conditionals using `then` the layout is disallowed
|
|
45
|
+
# # when the `else` body is multiline because it is treated as a lint offense.
|
|
46
|
+
# if something then on_the_same_line_as_then
|
|
47
|
+
# else first_line
|
|
48
|
+
# second_line
|
|
49
|
+
# end
|
|
50
|
+
#
|
|
51
|
+
# # good
|
|
52
|
+
#
|
|
53
|
+
# # For single-line conditional using `then` the layout is allowed
|
|
54
|
+
# # when `else` body is a single-line because it is treated as intentional.
|
|
55
|
+
#
|
|
56
|
+
# if something then on_the_same_line_as_then
|
|
57
|
+
# else single_line
|
|
58
|
+
# end
|
|
41
59
|
class ElseLayout < Base
|
|
42
60
|
include Alignment
|
|
43
61
|
include RangeHelp
|
|
@@ -47,6 +65,7 @@ module RuboCop
|
|
|
47
65
|
|
|
48
66
|
def on_if(node)
|
|
49
67
|
return if node.ternary?
|
|
68
|
+
return if node.then? && !node.else_branch&.begin_type?
|
|
50
69
|
|
|
51
70
|
# If the if is on a single line, it'll be handled by `Style/OneLineConditional`
|
|
52
71
|
return if node.single_line?
|
|
@@ -19,10 +19,23 @@ module RuboCop
|
|
|
19
19
|
MSG = 'Empty interpolation detected.'
|
|
20
20
|
|
|
21
21
|
def on_interpolation(begin_node)
|
|
22
|
-
return
|
|
22
|
+
return if in_percent_literal_array?(begin_node)
|
|
23
|
+
|
|
24
|
+
node_children = begin_node.children.dup
|
|
25
|
+
node_children.delete_if { |e| e.nil_type? || (e.basic_literal? && e.str_content&.empty?) }
|
|
26
|
+
return unless node_children.empty?
|
|
23
27
|
|
|
24
28
|
add_offense(begin_node) { |corrector| corrector.remove(begin_node) }
|
|
25
29
|
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def in_percent_literal_array?(begin_node)
|
|
34
|
+
array_node = begin_node.each_ancestor(:array).first
|
|
35
|
+
return false unless array_node
|
|
36
|
+
|
|
37
|
+
array_node.percent_literal?
|
|
38
|
+
end
|
|
26
39
|
end
|
|
27
40
|
end
|
|
28
41
|
end
|
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
|
94
94
|
when :float
|
|
95
95
|
true
|
|
96
96
|
when :send
|
|
97
|
-
|
|
97
|
+
float_send?(node)
|
|
98
98
|
when :begin
|
|
99
99
|
float?(node.children.first)
|
|
100
100
|
else
|
|
@@ -108,18 +108,18 @@ module RuboCop
|
|
|
108
108
|
(node.numeric_type? && node.value.zero?) || node.nil_type?
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
def
|
|
111
|
+
def float_send?(node)
|
|
112
112
|
if node.arithmetic_operation?
|
|
113
113
|
float?(node.receiver) || float?(node.first_argument)
|
|
114
114
|
elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
|
|
115
115
|
true
|
|
116
116
|
elsif node.receiver&.float_type?
|
|
117
117
|
FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
|
|
118
|
-
|
|
118
|
+
numeric_returning_method?(node)
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
def
|
|
122
|
+
def numeric_returning_method?(node)
|
|
123
123
|
return false unless node.receiver
|
|
124
124
|
|
|
125
125
|
case node.method_name
|
|
@@ -11,39 +11,43 @@ module RuboCop
|
|
|
11
11
|
# @example
|
|
12
12
|
# # bad
|
|
13
13
|
# foo.object_id == bar.object_id
|
|
14
|
+
# foo.object_id != baz.object_id
|
|
14
15
|
#
|
|
15
16
|
# # good
|
|
16
17
|
# foo.equal?(bar)
|
|
18
|
+
# !foo.equal?(baz)
|
|
17
19
|
#
|
|
18
20
|
class IdentityComparison < Base
|
|
19
21
|
extend AutoCorrector
|
|
20
22
|
|
|
21
|
-
MSG = 'Use
|
|
22
|
-
RESTRICT_ON_SEND = %i[==].freeze
|
|
23
|
+
MSG = 'Use `%<bang>sequal?` instead of `%<comparison_method>s` when comparing `object_id`.'
|
|
24
|
+
RESTRICT_ON_SEND = %i[== !=].freeze
|
|
25
|
+
|
|
26
|
+
# @!method object_id_comparison(node)
|
|
27
|
+
def_node_matcher :object_id_comparison, <<~PATTERN
|
|
28
|
+
(send
|
|
29
|
+
(send
|
|
30
|
+
_lhs_receiver :object_id) ${:== :!=}
|
|
31
|
+
(send
|
|
32
|
+
_rhs_receiver :object_id))
|
|
33
|
+
PATTERN
|
|
23
34
|
|
|
24
35
|
def on_send(node)
|
|
25
|
-
return unless
|
|
36
|
+
return unless (comparison_method = object_id_comparison(node))
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
bang = comparison_method == :== ? '' : '!'
|
|
39
|
+
add_offense(node,
|
|
40
|
+
message: format(MSG, comparison_method: comparison_method,
|
|
41
|
+
bang: bang)) do |corrector|
|
|
28
42
|
receiver = node.receiver.receiver
|
|
29
43
|
argument = node.first_argument.receiver
|
|
30
44
|
return unless receiver && argument
|
|
31
45
|
|
|
32
|
-
replacement = "#{receiver.source}.equal?(#{argument.source})"
|
|
46
|
+
replacement = "#{bang}#{receiver.source}.equal?(#{argument.source})"
|
|
33
47
|
|
|
34
48
|
corrector.replace(node, replacement)
|
|
35
49
|
end
|
|
36
50
|
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def compare_between_object_id_by_double_equal?(node)
|
|
41
|
-
object_id_method?(node.receiver) && object_id_method?(node.first_argument)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def object_id_method?(node)
|
|
45
|
-
node.send_type? && node.method?(:object_id)
|
|
46
|
-
end
|
|
47
51
|
end
|
|
48
52
|
end
|
|
49
53
|
end
|
|
@@ -54,6 +54,18 @@ module RuboCop
|
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
def on_or(node)
|
|
58
|
+
return unless node.lhs.falsey_literal?
|
|
59
|
+
|
|
60
|
+
add_offense(node.lhs) do |corrector|
|
|
61
|
+
# Don't autocorrect `'foo' && return` because having `return` as
|
|
62
|
+
# the leftmost node can lead to a void value expression syntax error.
|
|
63
|
+
next if node.rhs.type?(:return, :break, :next)
|
|
64
|
+
|
|
65
|
+
corrector.replace(node, node.rhs.source)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
57
69
|
def on_if(node)
|
|
58
70
|
cond = condition(node)
|
|
59
71
|
|
|
@@ -123,7 +135,9 @@ module RuboCop
|
|
|
123
135
|
# rubocop:enable Metrics/AbcSize
|
|
124
136
|
|
|
125
137
|
def on_case(case_node)
|
|
126
|
-
if case_node.condition
|
|
138
|
+
if (cond = case_node.condition)
|
|
139
|
+
return if !cond.falsey_literal? && !cond.truthy_literal?
|
|
140
|
+
|
|
127
141
|
check_case(case_node)
|
|
128
142
|
else
|
|
129
143
|
case_node.when_branches.each do |when_node|
|
|
@@ -228,7 +242,7 @@ module RuboCop
|
|
|
228
242
|
)
|
|
229
243
|
end
|
|
230
244
|
|
|
231
|
-
def condition_evaluation(node, cond)
|
|
245
|
+
def condition_evaluation?(node, cond)
|
|
232
246
|
if node.unless?
|
|
233
247
|
cond.falsey_literal?
|
|
234
248
|
else
|
|
@@ -238,32 +252,28 @@ module RuboCop
|
|
|
238
252
|
|
|
239
253
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
240
254
|
def correct_if_node(node, cond)
|
|
241
|
-
result = condition_evaluation(node, cond)
|
|
242
|
-
|
|
243
|
-
if node.elsif? && result
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
else
|
|
264
|
-
add_offense(cond) do |corrector|
|
|
265
|
-
corrector.remove(node)
|
|
266
|
-
end
|
|
255
|
+
result = condition_evaluation?(node, cond)
|
|
256
|
+
|
|
257
|
+
new_node = if node.elsif? && result
|
|
258
|
+
"else\n #{range_with_comments(node.if_branch).source}"
|
|
259
|
+
elsif node.elsif? && !result
|
|
260
|
+
"else\n #{node.else_branch.source}"
|
|
261
|
+
elsif node.if_branch && result
|
|
262
|
+
node.if_branch.source
|
|
263
|
+
elsif node.elsif_conditional?
|
|
264
|
+
"#{node.else_branch.source.sub('elsif', 'if')}\nend"
|
|
265
|
+
elsif node.else? || node.ternary?
|
|
266
|
+
node.else_branch.source
|
|
267
|
+
else
|
|
268
|
+
'' # Equivalent to removing the node
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
add_offense(cond) do |corrector|
|
|
272
|
+
next if part_of_ignored_node?(node)
|
|
273
|
+
|
|
274
|
+
corrector.replace(node, new_node)
|
|
275
|
+
|
|
276
|
+
ignore_node(node)
|
|
267
277
|
end
|
|
268
278
|
end
|
|
269
279
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
|
66
66
|
|
|
67
67
|
def special_keyword?(node)
|
|
68
68
|
# handle strings like __FILE__
|
|
69
|
-
(node.str_type? && !node.loc
|
|
69
|
+
(node.str_type? && !node.loc?(:begin)) || node.source_range.is?('__LINE__')
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def array_in_regexp?(node)
|
|
@@ -9,9 +9,21 @@ module RuboCop
|
|
|
9
9
|
# cop disables on wide ranges of code, that latter contributors to
|
|
10
10
|
# a file wouldn't be aware of.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
12
|
+
# You can set `MaximumRangeSize` to define the maximum number of
|
|
13
|
+
# consecutive lines a cop can be disabled for.
|
|
14
|
+
#
|
|
15
|
+
# - `.inf` any size (default)
|
|
16
|
+
# - `0` allows only single-line disables
|
|
17
|
+
# - `1` means the maximum allowed is as follows:
|
|
18
|
+
#
|
|
19
|
+
# [source,ruby]
|
|
20
|
+
# ----
|
|
21
|
+
# # rubocop:disable SomeCop
|
|
22
|
+
# a = 1
|
|
23
|
+
# # rubocop:enable SomeCop
|
|
24
|
+
# ----
|
|
25
|
+
#
|
|
26
|
+
# @example MaximumRangeSize: .inf (default)
|
|
15
27
|
#
|
|
16
28
|
# # good
|
|
17
29
|
# # rubocop:disable Layout/SpaceAroundOperators
|
|
@@ -25,9 +37,7 @@ module RuboCop
|
|
|
25
37
|
# x= 0
|
|
26
38
|
# # EOF
|
|
27
39
|
#
|
|
28
|
-
# @example
|
|
29
|
-
# # Lint/MissingCopEnableDirective:
|
|
30
|
-
# # MaximumRangeSize: 2
|
|
40
|
+
# @example MaximumRangeSize: 2
|
|
31
41
|
#
|
|
32
42
|
# # good
|
|
33
43
|
# # rubocop:disable Layout/SpaceAroundOperators
|
|
@@ -52,10 +62,9 @@ module RuboCop
|
|
|
52
62
|
each_missing_enable do |cop, line_range|
|
|
53
63
|
next if acceptable_range?(cop, line_range)
|
|
54
64
|
|
|
55
|
-
range = source_range(processed_source.buffer, line_range.min, 0..0)
|
|
56
65
|
comment = processed_source.comment_at_line(line_range.begin)
|
|
57
66
|
|
|
58
|
-
add_offense(
|
|
67
|
+
add_offense(comment, message: message(cop, comment))
|
|
59
68
|
end
|
|
60
69
|
end
|
|
61
70
|
|
|
@@ -112,22 +112,36 @@ module RuboCop
|
|
|
112
112
|
|
|
113
113
|
def each_line_range(cop, line_ranges)
|
|
114
114
|
line_ranges.each_with_index do |line_range, line_range_index|
|
|
115
|
-
next if
|
|
116
|
-
next if expected_final_disable?(cop, line_range)
|
|
115
|
+
next if should_skip_line_range?(cop, line_range)
|
|
117
116
|
|
|
118
117
|
comment = processed_source.comment_at_line(line_range.begin)
|
|
119
|
-
|
|
120
|
-
find_redundant_all(line_range, line_ranges[line_range_index + 1])
|
|
121
|
-
elsif department_disabled?(cop, comment)
|
|
122
|
-
find_redundant_department(cop, line_range)
|
|
123
|
-
else
|
|
124
|
-
find_redundant_cop(cop, line_range)
|
|
125
|
-
end
|
|
118
|
+
next if skip_directive?(comment)
|
|
126
119
|
|
|
120
|
+
next_range = line_ranges[line_range_index + 1]
|
|
121
|
+
redundant = find_redundant_directive(cop, comment, line_range, next_range)
|
|
127
122
|
yield comment, redundant if redundant
|
|
128
123
|
end
|
|
129
124
|
end
|
|
130
125
|
|
|
126
|
+
def should_skip_line_range?(cop, line_range)
|
|
127
|
+
ignore_offense?(line_range) || expected_final_disable?(cop, line_range)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def skip_directive?(comment)
|
|
131
|
+
directive = DirectiveComment.new(comment)
|
|
132
|
+
directive.push? || directive.pop?
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def find_redundant_directive(cop, comment, line_range, next_range)
|
|
136
|
+
if all_disabled?(comment)
|
|
137
|
+
find_redundant_all(line_range, next_range)
|
|
138
|
+
elsif department_disabled?(cop, comment)
|
|
139
|
+
find_redundant_department(cop, line_range)
|
|
140
|
+
else
|
|
141
|
+
find_redundant_cop(cop, line_range)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
131
145
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
132
146
|
def each_already_disabled(cop, line_ranges)
|
|
133
147
|
line_ranges.each_cons(2) do |previous_range, range|
|
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def redundant_group?(expr)
|
|
76
|
-
expr.is?(:passive, :group) && expr.
|
|
76
|
+
expr.is?(:passive, :group) && expr.one? { |child| child.type != :free_space }
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def redundantly_quantifiable?(node)
|
|
@@ -19,7 +19,8 @@ module RuboCop
|
|
|
19
19
|
# * 2.2+ ... Add `rational` and `complex` above
|
|
20
20
|
# * 2.7+ ... Add `ruby2_keywords` above
|
|
21
21
|
# * 3.1+ ... Add `fiber` above
|
|
22
|
-
# * 3.2+ ... `set`
|
|
22
|
+
# * 3.2+ ... Add `set` above
|
|
23
|
+
# * 4.0+ ... Add `pathname` above
|
|
23
24
|
#
|
|
24
25
|
# This cop target those features.
|
|
25
26
|
#
|
|
@@ -69,7 +70,8 @@ module RuboCop
|
|
|
69
70
|
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
|
70
71
|
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
|
71
72
|
(target_ruby_version >= 3.1 && feature_name == 'fiber') ||
|
|
72
|
-
(target_ruby_version >= 3.2 && feature_name == 'set')
|
|
73
|
+
(target_ruby_version >= 3.2 && feature_name == 'set') ||
|
|
74
|
+
(target_ruby_version >= 4.0 && feature_name == 'pathname')
|
|
73
75
|
end
|
|
74
76
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
75
77
|
end
|
|
@@ -20,6 +20,15 @@ module RuboCop
|
|
|
20
20
|
# In the example below, the safe navigation operator (`&.`) is unnecessary
|
|
21
21
|
# because `NilClass` has methods like `respond_to?` and `is_a?`.
|
|
22
22
|
#
|
|
23
|
+
# The `InferNonNilReceiver` option specifies whether to look into previous code
|
|
24
|
+
# paths to infer if the receiver can't be nil. This check is unsafe because the receiver
|
|
25
|
+
# can be redefined between the safe navigation call and previous regular method call.
|
|
26
|
+
# It does the inference only in the current scope, e.g. within the same method definition etc.
|
|
27
|
+
#
|
|
28
|
+
# The `AdditionalNilMethods` option specifies additional custom methods which are
|
|
29
|
+
# defined on `NilClass`. When `InferNonNilReceiver` is set, they are used to determine
|
|
30
|
+
# whether the receiver can be nil.
|
|
31
|
+
#
|
|
23
32
|
# @safety
|
|
24
33
|
# This cop is unsafe, because autocorrection can change the return type of
|
|
25
34
|
# the expression. An offending expression that previously could return `nil`
|
|
@@ -33,6 +42,20 @@ module RuboCop
|
|
|
33
42
|
# CamelCaseConst.do_something
|
|
34
43
|
#
|
|
35
44
|
# # bad
|
|
45
|
+
# foo.to_s&.strip
|
|
46
|
+
# foo.to_i&.zero?
|
|
47
|
+
# foo.to_f&.zero?
|
|
48
|
+
# foo.to_a&.size
|
|
49
|
+
# foo.to_h&.size
|
|
50
|
+
#
|
|
51
|
+
# # good
|
|
52
|
+
# foo.to_s.strip
|
|
53
|
+
# foo.to_i.zero?
|
|
54
|
+
# foo.to_f.zero?
|
|
55
|
+
# foo.to_a.size
|
|
56
|
+
# foo.to_h.size
|
|
57
|
+
#
|
|
58
|
+
# # bad
|
|
36
59
|
# do_something if attrs&.respond_to?(:[])
|
|
37
60
|
#
|
|
38
61
|
# # good
|
|
@@ -81,17 +104,59 @@ module RuboCop
|
|
|
81
104
|
# do_something if attrs.nil_safe_method(:[])
|
|
82
105
|
# do_something if attrs&.not_nil_safe_method(:[])
|
|
83
106
|
#
|
|
107
|
+
# @example InferNonNilReceiver: false (default)
|
|
108
|
+
# # good
|
|
109
|
+
# foo.bar
|
|
110
|
+
# foo&.baz
|
|
111
|
+
#
|
|
112
|
+
# @example InferNonNilReceiver: true
|
|
113
|
+
# # bad
|
|
114
|
+
# foo.bar
|
|
115
|
+
# foo&.baz # would raise on previous line if `foo` is nil
|
|
116
|
+
#
|
|
117
|
+
# # good
|
|
118
|
+
# foo.bar
|
|
119
|
+
# foo.baz
|
|
120
|
+
#
|
|
121
|
+
# # bad
|
|
122
|
+
# if foo.condition?
|
|
123
|
+
# foo&.bar
|
|
124
|
+
# end
|
|
125
|
+
#
|
|
126
|
+
# # good
|
|
127
|
+
# if foo.condition?
|
|
128
|
+
# foo.bar
|
|
129
|
+
# end
|
|
130
|
+
#
|
|
131
|
+
# # good (different scopes)
|
|
132
|
+
# def method1
|
|
133
|
+
# foo.bar
|
|
134
|
+
# end
|
|
135
|
+
#
|
|
136
|
+
# def method2
|
|
137
|
+
# foo&.bar
|
|
138
|
+
# end
|
|
139
|
+
#
|
|
140
|
+
# @example AdditionalNilMethods: [present?]
|
|
141
|
+
# # good
|
|
142
|
+
# foo.present?
|
|
143
|
+
# foo&.bar
|
|
144
|
+
#
|
|
84
145
|
class RedundantSafeNavigation < Base
|
|
85
146
|
include AllowedMethods
|
|
86
147
|
extend AutoCorrector
|
|
87
148
|
|
|
88
149
|
MSG = 'Redundant safe navigation detected, use `.` instead.'
|
|
89
150
|
MSG_LITERAL = 'Redundant safe navigation with default literal detected.'
|
|
151
|
+
MSG_NON_NIL = 'Redundant safe navigation on non-nil receiver (detected by analyzing ' \
|
|
152
|
+
'previous code/method invocations).'
|
|
90
153
|
|
|
91
154
|
NIL_SPECIFIC_METHODS = (nil.methods - Object.new.methods).to_set.freeze
|
|
92
155
|
|
|
93
156
|
SNAKE_CASE = /\A[[:digit:][:upper:]_]+\z/.freeze
|
|
94
157
|
|
|
158
|
+
GUARANTEED_INSTANCE_METHODS = %i[to_s to_i to_f to_a to_h].freeze
|
|
159
|
+
|
|
95
160
|
# @!method respond_to_nil_specific_method?(node)
|
|
96
161
|
def_node_matcher :respond_to_nil_specific_method?, <<~PATTERN
|
|
97
162
|
(csend _ :respond_to? (sym %NIL_SPECIFIC_METHODS))
|
|
@@ -111,15 +176,27 @@ module RuboCop
|
|
|
111
176
|
|
|
112
177
|
# rubocop:disable Metrics/AbcSize
|
|
113
178
|
def on_csend(node)
|
|
179
|
+
range = node.loc.dot
|
|
180
|
+
|
|
181
|
+
if infer_non_nil_receiver?
|
|
182
|
+
checker = Lint::Utils::NilReceiverChecker.new(node.receiver, additional_nil_methods)
|
|
183
|
+
|
|
184
|
+
if checker.cant_be_nil?
|
|
185
|
+
add_offense(range, message: MSG_NON_NIL) { |corrector| corrector.replace(range, '.') }
|
|
186
|
+
return
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
114
190
|
unless assume_receiver_instance_exists?(node.receiver)
|
|
115
|
-
return
|
|
191
|
+
return if !guaranteed_instance?(node.receiver) && !check?(node)
|
|
116
192
|
return if respond_to_nil_specific_method?(node)
|
|
117
193
|
end
|
|
118
194
|
|
|
119
|
-
range = node.loc.dot
|
|
120
195
|
add_offense(range) { |corrector| corrector.replace(range, '.') }
|
|
121
196
|
end
|
|
197
|
+
# rubocop:enable Metrics/AbcSize
|
|
122
198
|
|
|
199
|
+
# rubocop:disable Metrics/AbcSize
|
|
123
200
|
def on_or(node)
|
|
124
201
|
conversion_with_default?(node) do |send_node|
|
|
125
202
|
range = send_node.loc.dot.begin.join(node.source_range.end)
|
|
@@ -142,7 +219,20 @@ module RuboCop
|
|
|
142
219
|
receiver.self_type? || (receiver.literal? && !receiver.nil_type?)
|
|
143
220
|
end
|
|
144
221
|
|
|
222
|
+
def guaranteed_instance?(node)
|
|
223
|
+
receiver = if node.any_block_type?
|
|
224
|
+
node.send_node
|
|
225
|
+
else
|
|
226
|
+
node
|
|
227
|
+
end
|
|
228
|
+
return false unless receiver.send_type?
|
|
229
|
+
|
|
230
|
+
GUARANTEED_INSTANCE_METHODS.include?(receiver.method_name)
|
|
231
|
+
end
|
|
232
|
+
|
|
145
233
|
def check?(node)
|
|
234
|
+
return false unless allowed_method?(node.method_name)
|
|
235
|
+
|
|
146
236
|
parent = node.parent
|
|
147
237
|
return false unless parent
|
|
148
238
|
|
|
@@ -154,6 +244,15 @@ module RuboCop
|
|
|
154
244
|
def condition?(parent, node)
|
|
155
245
|
(parent.conditional? || parent.post_condition_loop?) && parent.condition == node
|
|
156
246
|
end
|
|
247
|
+
|
|
248
|
+
def infer_non_nil_receiver?
|
|
249
|
+
cop_config['InferNonNilReceiver']
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def additional_nil_methods
|
|
253
|
+
@additional_nil_methods ||=
|
|
254
|
+
Array(cop_config.fetch('AdditionalNilMethods', []).map(&:to_sym))
|
|
255
|
+
end
|
|
157
256
|
end
|
|
158
257
|
end
|
|
159
258
|
end
|
|
@@ -144,7 +144,9 @@ module RuboCop
|
|
|
144
144
|
expression = node.parent.source_range if node.parent.array_type?
|
|
145
145
|
[expression, variable.source]
|
|
146
146
|
elsif !variable.array_type?
|
|
147
|
-
|
|
147
|
+
replacement = variable.source
|
|
148
|
+
replacement = "[#{replacement}]" if wrap_in_brackets?(node)
|
|
149
|
+
[expression, replacement]
|
|
148
150
|
elsif redundant_brackets?(node)
|
|
149
151
|
[expression, remove_brackets(variable)]
|
|
150
152
|
else
|
|
@@ -176,6 +178,10 @@ module RuboCop
|
|
|
176
178
|
grandparent&.resbody_type?
|
|
177
179
|
end
|
|
178
180
|
|
|
181
|
+
def wrap_in_brackets?(node)
|
|
182
|
+
node.parent.array_type? && !node.parent.bracketed?
|
|
183
|
+
end
|
|
184
|
+
|
|
179
185
|
def remove_brackets(array)
|
|
180
186
|
array_start = array.loc.begin.source
|
|
181
187
|
elements = *array
|