rubocop 1.57.2 → 1.62.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/LICENSE.txt +1 -1
- data/README.md +4 -4
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +87 -15
- data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli.rb +6 -1
- data/lib/rubocop/config.rb +4 -2
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_obsoletion.rb +11 -8
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +17 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +123 -29
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +22 -7
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -3
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +50 -20
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -4
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -3
- data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
- data/lib/rubocop/cop/lint/number_conversion.rb +9 -4
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +54 -6
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -4
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +7 -2
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +7 -2
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_times.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +20 -2
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +12 -4
- data/lib/rubocop/cop/naming/constant_name.rb +1 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +152 -21
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/case_like_if.rb +5 -5
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +18 -8
- data/lib/rubocop/cop/style/combinable_loops.rb +13 -7
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -7
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -14
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +105 -11
- data/lib/rubocop/cop/style/hash_except.rb +2 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +44 -2
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +8 -10
- data/lib/rubocop/cop/style/map_to_hash.rb +17 -7
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +14 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +4 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +4 -3
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +3 -3
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +27 -7
- data/lib/rubocop/cop/style/redundant_parentheses.rb +33 -10
- data/lib/rubocop/cop/style/redundant_return.rb +7 -1
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- data/lib/rubocop/cop/style/redundant_sort.rb +9 -8
- data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +3 -4
- data/lib/rubocop/cop/style/select_by_regexp.rb +7 -6
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +8 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +5 -2
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +15 -3
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/html_formatter.rb +31 -12
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +2 -2
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +5 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +29 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +11 -8
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/result_cache.rb +0 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +8 -8
- data/lib/rubocop/rspec/shared_contexts.rb +40 -15
- data/lib/rubocop/rspec/support.rb +2 -0
- data/lib/rubocop/runner.rb +10 -3
- data/lib/rubocop/server/cache.rb +1 -2
- data/lib/rubocop/server/client_command/exec.rb +0 -1
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +18 -3
- data/lib/rubocop.rb +4 -0
- metadata +18 -10
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -5,7 +5,8 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# Checks for redundant safe navigation calls.
|
7
7
|
# Use cases where a constant, named in camel case for classes and modules is `nil` are rare,
|
8
|
-
# and an offense is not detected when the receiver is a
|
8
|
+
# and an offense is not detected when the receiver is a constant. The detection also applies
|
9
|
+
# to literal receivers, except for `nil`.
|
9
10
|
#
|
10
11
|
# For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`,
|
11
12
|
# and `equal?` methods are checked by default.
|
@@ -50,6 +51,22 @@ module RuboCop
|
|
50
51
|
# # good - without `&.` this will always return `true`
|
51
52
|
# foo&.respond_to?(:to_a)
|
52
53
|
#
|
54
|
+
# # bad - for `nil`s conversion methods return default values for the type
|
55
|
+
# foo&.to_h || {}
|
56
|
+
# foo&.to_h { |k, v| [k, v] } || {}
|
57
|
+
# foo&.to_a || []
|
58
|
+
# foo&.to_i || 0
|
59
|
+
# foo&.to_f || 0.0
|
60
|
+
# foo&.to_s || ''
|
61
|
+
#
|
62
|
+
# # good
|
63
|
+
# foo.to_h
|
64
|
+
# foo.to_h { |k, v| [k, v] }
|
65
|
+
# foo.to_a
|
66
|
+
# foo.to_i
|
67
|
+
# foo.to_f
|
68
|
+
# foo.to_s
|
69
|
+
#
|
53
70
|
# @example AllowedMethods: [nil_safe_method]
|
54
71
|
# # bad
|
55
72
|
# do_something if attrs&.nil_safe_method(:[])
|
@@ -60,10 +77,10 @@ module RuboCop
|
|
60
77
|
#
|
61
78
|
class RedundantSafeNavigation < Base
|
62
79
|
include AllowedMethods
|
63
|
-
include RangeHelp
|
64
80
|
extend AutoCorrector
|
65
81
|
|
66
|
-
MSG = 'Redundant safe navigation detected.'
|
82
|
+
MSG = 'Redundant safe navigation detected, use `.` instead.'
|
83
|
+
MSG_LITERAL = 'Redundant safe navigation with default literal detected.'
|
67
84
|
|
68
85
|
NIL_SPECIFIC_METHODS = (nil.methods - Object.new.methods).to_set.freeze
|
69
86
|
|
@@ -74,20 +91,51 @@ module RuboCop
|
|
74
91
|
(csend _ :respond_to? (sym %NIL_SPECIFIC_METHODS))
|
75
92
|
PATTERN
|
76
93
|
|
94
|
+
# @!method conversion_with_default?(node)
|
95
|
+
def_node_matcher :conversion_with_default?, <<~PATTERN
|
96
|
+
{
|
97
|
+
(or $(csend _ :to_h) (hash))
|
98
|
+
(or (block $(csend _ :to_h) ...) (hash))
|
99
|
+
(or $(csend _ :to_a) (array))
|
100
|
+
(or $(csend _ :to_i) (int 0))
|
101
|
+
(or $(csend _ :to_f) (float 0.0))
|
102
|
+
(or $(csend _ :to_s) (str empty?))
|
103
|
+
}
|
104
|
+
PATTERN
|
105
|
+
|
77
106
|
# rubocop:disable Metrics/AbcSize
|
78
107
|
def on_csend(node)
|
79
|
-
unless
|
108
|
+
unless assume_receiver_instance_exists?(node.receiver)
|
80
109
|
return unless check?(node) && allowed_method?(node.method_name)
|
81
110
|
return if respond_to_nil_specific_method?(node)
|
82
111
|
end
|
83
112
|
|
84
|
-
range =
|
85
|
-
add_offense(range) { |corrector| corrector.replace(
|
113
|
+
range = node.loc.dot
|
114
|
+
add_offense(range) { |corrector| corrector.replace(range, '.') }
|
115
|
+
end
|
116
|
+
|
117
|
+
def on_or(node)
|
118
|
+
conversion_with_default?(node) do |send_node|
|
119
|
+
range = send_node.loc.dot.begin.join(node.source_range.end)
|
120
|
+
|
121
|
+
add_offense(range, message: MSG_LITERAL) do |corrector|
|
122
|
+
corrector.replace(send_node.loc.dot, '.')
|
123
|
+
|
124
|
+
range_with_default = node.lhs.source_range.end.begin.join(node.source_range.end)
|
125
|
+
corrector.remove(range_with_default)
|
126
|
+
end
|
127
|
+
end
|
86
128
|
end
|
87
129
|
# rubocop:enable Metrics/AbcSize
|
88
130
|
|
89
131
|
private
|
90
132
|
|
133
|
+
def assume_receiver_instance_exists?(receiver)
|
134
|
+
return true if receiver.const_type? && !receiver.source.match?(SNAKE_CASE)
|
135
|
+
|
136
|
+
receiver.literal? && !receiver.nil_type?
|
137
|
+
end
|
138
|
+
|
91
139
|
def check?(node)
|
92
140
|
parent = node.parent
|
93
141
|
return false unless parent
|
@@ -34,6 +34,7 @@ module RuboCop
|
|
34
34
|
MSG_WITH_INDEX = 'Remove redundant `with_index`.'
|
35
35
|
|
36
36
|
def on_block(node)
|
37
|
+
return unless node.receiver
|
37
38
|
return unless (send = redundant_with_index?(node))
|
38
39
|
|
39
40
|
range = with_index_range(send)
|
@@ -56,10 +57,10 @@ module RuboCop
|
|
56
57
|
def_node_matcher :redundant_with_index?, <<~PATTERN
|
57
58
|
{
|
58
59
|
(block
|
59
|
-
$(
|
60
|
+
$(call _ {:each_with_index :with_index} ...)
|
60
61
|
(args (arg _)) ...)
|
61
62
|
(numblock
|
62
|
-
$(
|
63
|
+
$(call _ {:each_with_index :with_index} ...) 1 ...)
|
63
64
|
}
|
64
65
|
PATTERN
|
65
66
|
|
@@ -56,9 +56,9 @@ module RuboCop
|
|
56
56
|
def_node_matcher :redundant_with_object?, <<~PATTERN
|
57
57
|
{
|
58
58
|
(block
|
59
|
-
$(
|
59
|
+
$(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
|
60
60
|
(numblock
|
61
|
-
$(
|
61
|
+
$(call _ {:each_with_object :with_object} _) 1 ...)
|
62
62
|
}
|
63
63
|
PATTERN
|
64
64
|
|
@@ -59,9 +59,7 @@ module RuboCop
|
|
59
59
|
|
60
60
|
def autocorrect(corrector, node)
|
61
61
|
rescued, _, _body = *node
|
62
|
-
range =
|
63
|
-
node.loc.keyword.end_pos,
|
64
|
-
rescued.source_range.end_pos)
|
62
|
+
range = node.loc.keyword.end.join(rescued.source_range.end)
|
65
63
|
|
66
64
|
corrector.replace(range, correction(*rescued))
|
67
65
|
end
|
@@ -45,10 +45,9 @@ module RuboCop
|
|
45
45
|
bad_method?(node) do |safe_nav, method|
|
46
46
|
return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
node.source_range.end_pos)
|
48
|
+
begin_range = node.loc.dot || safe_nav.source_range.end
|
49
|
+
location = begin_range.join(node.source_range.end)
|
50
|
+
|
52
51
|
add_offense(location) do |corrector|
|
53
52
|
autocorrect(corrector, offense_range: location, send_node: node)
|
54
53
|
end
|
@@ -46,14 +46,14 @@ module RuboCop
|
|
46
46
|
message = format_message_from(processed_source)
|
47
47
|
|
48
48
|
add_offense(comment, message: message) do
|
49
|
-
autocorrect
|
49
|
+
autocorrect if autocorrect_requested?
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
private
|
54
54
|
|
55
|
-
def autocorrect
|
56
|
-
FileUtils.chmod('+x',
|
55
|
+
def autocorrect
|
56
|
+
FileUtils.chmod('+x', processed_source.file_path)
|
57
57
|
end
|
58
58
|
|
59
59
|
def executable?(processed_source)
|
@@ -10,11 +10,18 @@ module RuboCop
|
|
10
10
|
# foo = foo
|
11
11
|
# foo, bar = foo, bar
|
12
12
|
# Foo = Foo
|
13
|
+
# hash['foo'] = hash['foo']
|
14
|
+
# obj.attr = obj.attr
|
13
15
|
#
|
14
16
|
# # good
|
15
17
|
# foo = bar
|
16
18
|
# foo, bar = bar, foo
|
17
19
|
# Foo = Bar
|
20
|
+
# hash['foo'] = hash['bar']
|
21
|
+
# obj.attr = obj.attr2
|
22
|
+
#
|
23
|
+
# # good (method calls possibly can return different results)
|
24
|
+
# hash[foo] = hash[foo]
|
18
25
|
#
|
19
26
|
class SelfAssignment < Base
|
20
27
|
MSG = 'Self-assignment detected.'
|
@@ -26,6 +33,15 @@ module RuboCop
|
|
26
33
|
gvasgn: :gvar
|
27
34
|
}.freeze
|
28
35
|
|
36
|
+
def on_send(node)
|
37
|
+
if node.method?(:[]=)
|
38
|
+
handle_key_assignment(node) if node.arguments.size == 2
|
39
|
+
elsif node.assignment_method?
|
40
|
+
handle_attribute_assignment(node) if node.arguments.size == 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
alias on_csend on_send
|
44
|
+
|
29
45
|
def on_lvasgn(node)
|
30
46
|
lhs, rhs = *node
|
31
47
|
return unless rhs
|
@@ -72,6 +88,28 @@ module RuboCop
|
|
72
88
|
rhs.type == ASSIGNMENT_TYPE_TO_RHS_TYPE[lhs.type] &&
|
73
89
|
rhs.children.first == lhs.children.first
|
74
90
|
end
|
91
|
+
|
92
|
+
def handle_key_assignment(node)
|
93
|
+
value_node = node.arguments[1]
|
94
|
+
|
95
|
+
if value_node.send_type? && value_node.method?(:[]) &&
|
96
|
+
node.receiver == value_node.receiver &&
|
97
|
+
!node.first_argument.call_type? &&
|
98
|
+
node.first_argument == value_node.first_argument
|
99
|
+
add_offense(node)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def handle_attribute_assignment(node)
|
104
|
+
first_argument = node.first_argument
|
105
|
+
return unless first_argument.respond_to?(:arguments) && first_argument.arguments.empty?
|
106
|
+
|
107
|
+
if first_argument.call_type? &&
|
108
|
+
node.receiver == first_argument.receiver &&
|
109
|
+
first_argument.method_name.to_s == node.method_name.to_s.delete_suffix('=')
|
110
|
+
add_offense(node)
|
111
|
+
end
|
112
|
+
end
|
75
113
|
end
|
76
114
|
end
|
77
115
|
end
|
@@ -123,6 +123,7 @@ module RuboCop
|
|
123
123
|
|
124
124
|
# Shorthand assignments always use their arguments
|
125
125
|
next false if assignment_node.shorthand_asgn?
|
126
|
+
next false unless assignment_node.parent
|
126
127
|
|
127
128
|
node_within_block_or_conditional =
|
128
129
|
node_within_block_or_conditional?(assignment_node.parent, argument.scope.node)
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
19
19
|
# 'underscored_string'.to_sym
|
20
20
|
# :'underscored_symbol'
|
21
21
|
# 'hyphenated-string'.to_sym
|
22
|
+
# "string_#{interpolation}".to_sym
|
22
23
|
#
|
23
24
|
# # good
|
24
25
|
# :string
|
@@ -26,6 +27,7 @@ module RuboCop
|
|
26
27
|
# :underscored_string
|
27
28
|
# :underscored_symbol
|
28
29
|
# :'hyphenated-string'
|
30
|
+
# :"string_#{interpolation}"
|
29
31
|
#
|
30
32
|
# @example EnforcedStyle: strict (default)
|
31
33
|
#
|
@@ -75,9 +77,12 @@ module RuboCop
|
|
75
77
|
|
76
78
|
def on_send(node)
|
77
79
|
return unless node.receiver
|
78
|
-
return unless node.receiver.str_type? || node.receiver.sym_type?
|
79
80
|
|
80
|
-
|
81
|
+
if node.receiver.str_type? || node.receiver.sym_type?
|
82
|
+
register_offense(node, correction: node.receiver.value.to_sym.inspect)
|
83
|
+
elsif node.receiver.dstr_type?
|
84
|
+
register_offense(node, correction: ":\"#{node.receiver.value.to_sym}\"")
|
85
|
+
end
|
81
86
|
end
|
82
87
|
|
83
88
|
def on_sym(node)
|
@@ -17,9 +17,12 @@ module RuboCop
|
|
17
17
|
private
|
18
18
|
|
19
19
|
def add_offense_from_diagnostic(diagnostic, ruby_version)
|
20
|
-
message =
|
21
|
-
|
22
|
-
|
20
|
+
message = if LSP.enabled?
|
21
|
+
diagnostic.message
|
22
|
+
else
|
23
|
+
"#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
|
24
|
+
'configure using `TargetRubyVersion` parameter, under `AllCops`)'
|
25
|
+
end
|
23
26
|
add_offense(diagnostic.location, message: message, severity: diagnostic.level)
|
24
27
|
end
|
25
28
|
|
@@ -51,8 +51,13 @@ module RuboCop
|
|
51
51
|
enum_conversion_call?(node) do |method_node, arguments|
|
52
52
|
next if method_node.call_type? &&
|
53
53
|
!method_node.method?(:__method__) && !method_node.method?(:__callee__)
|
54
|
-
|
55
|
-
|
54
|
+
|
55
|
+
valid = if method_name?(method_node, def_node.method_name)
|
56
|
+
arguments_match?(arguments, def_node)
|
57
|
+
else
|
58
|
+
def_node.arguments.empty?
|
59
|
+
end
|
60
|
+
return if valid
|
56
61
|
|
57
62
|
add_offense(node)
|
58
63
|
end
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
34
34
|
MSG = 'Avoid leaving a trailing comma in attribute declarations.'
|
35
35
|
|
36
36
|
def on_send(node)
|
37
|
-
return unless node.attribute_accessor? && node.
|
37
|
+
return unless node.attribute_accessor? && node.last_argument.def_type?
|
38
38
|
|
39
39
|
trailing_comma = trailing_comma_range(node)
|
40
40
|
|
@@ -69,8 +69,8 @@ module RuboCop
|
|
69
69
|
# @!method reduce_with_block?(node)
|
70
70
|
def_node_matcher :reduce_with_block?, <<~PATTERN
|
71
71
|
{
|
72
|
-
(block (
|
73
|
-
(numblock (
|
72
|
+
(block (call _recv {:reduce :inject} ...) args ...)
|
73
|
+
(numblock (call _recv {:reduce :inject} ...) ...)
|
74
74
|
}
|
75
75
|
PATTERN
|
76
76
|
|
@@ -256,7 +256,7 @@ module RuboCop
|
|
256
256
|
|
257
257
|
def any_method_definition?(child)
|
258
258
|
cop_config.fetch('MethodCreatingMethods', []).any? do |m|
|
259
|
-
matcher_name = "#{m}_method?"
|
259
|
+
matcher_name = :"#{m}_method?"
|
260
260
|
unless respond_to?(matcher_name)
|
261
261
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
262
262
|
{def (send nil? :#{m} ...)}
|
@@ -279,7 +279,7 @@ module RuboCop
|
|
279
279
|
|
280
280
|
def any_context_creating_methods?(child)
|
281
281
|
cop_config.fetch('ContextCreatingMethods', []).any? do |m|
|
282
|
-
matcher_name = "#{m}_block?"
|
282
|
+
matcher_name = :"#{m}_block?"
|
283
283
|
unless respond_to?(matcher_name)
|
284
284
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
285
285
|
({block numblock} (send {nil? const} {:#{m}} ...) ...)
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
6
|
# Checks for uses of `Integer#times` that will never yield
|
7
|
-
# (when the integer
|
7
|
+
# (when the integer ``<= 0``) or that will only ever yield once
|
8
8
|
# (`1.times`).
|
9
9
|
#
|
10
10
|
# @safety
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
64
64
|
remove_node(corrector, node)
|
65
65
|
elsif !proc_name.empty?
|
66
66
|
autocorrect_block_pass(corrector, node, proc_name)
|
67
|
-
|
67
|
+
elsif node.block_type?
|
68
68
|
autocorrect_block(corrector, node)
|
69
69
|
end
|
70
70
|
end
|
@@ -100,7 +100,12 @@ module RuboCop
|
|
100
100
|
expressions = *node
|
101
101
|
expressions.pop unless in_void_context?(node)
|
102
102
|
expressions.each do |expr|
|
103
|
-
check_void_op(expr)
|
103
|
+
check_void_op(expr) do
|
104
|
+
block_node = node.each_ancestor(:block).first
|
105
|
+
|
106
|
+
block_node&.method?(:each)
|
107
|
+
end
|
108
|
+
|
104
109
|
check_expression(expr)
|
105
110
|
end
|
106
111
|
end
|
@@ -144,7 +149,7 @@ module RuboCop
|
|
144
149
|
end
|
145
150
|
|
146
151
|
def check_literal(node)
|
147
|
-
return if !node
|
152
|
+
return if !entirely_literal?(node) || node.xstr_type? || node.range_type?
|
148
153
|
|
149
154
|
add_offense(node, message: format(LIT_MSG, lit: node.source)) do |corrector|
|
150
155
|
autocorrect_void_expression(corrector, node)
|
@@ -217,6 +222,19 @@ module RuboCop
|
|
217
222
|
end
|
218
223
|
corrector.replace(send_node.loc.selector, suggestion)
|
219
224
|
end
|
225
|
+
|
226
|
+
def entirely_literal?(node)
|
227
|
+
case node.type
|
228
|
+
when :array
|
229
|
+
node.each_value.all? { |value| entirely_literal?(value) }
|
230
|
+
when :hash
|
231
|
+
return false unless node.each_key.all? { |key| entirely_literal?(key) }
|
232
|
+
|
233
|
+
node.each_value.all? { |value| entirely_literal?(value) }
|
234
|
+
else
|
235
|
+
node.literal?
|
236
|
+
end
|
237
|
+
end
|
220
238
|
end
|
221
239
|
end
|
222
240
|
end
|
@@ -10,9 +10,9 @@ module RuboCop
|
|
10
10
|
#
|
11
11
|
# Interpreting ABC size:
|
12
12
|
#
|
13
|
-
# *
|
14
|
-
# * 18..30 unsatisfactory
|
15
|
-
# *
|
13
|
+
# * ``<= 17`` satisfactory
|
14
|
+
# * `18..30` unsatisfactory
|
15
|
+
# * `>` 30 dangerous
|
16
16
|
#
|
17
17
|
# You can have repeated "attributes" calls count as a single "branch".
|
18
18
|
# For this purpose, attributes are any method with no argument; no attempt
|
@@ -218,7 +218,7 @@ module RuboCop
|
|
218
218
|
|
219
219
|
# @api private
|
220
220
|
def already_on_multiple_lines?(node)
|
221
|
-
return node.first_line != node.
|
221
|
+
return node.first_line != node.last_argument.last_line if node.def_type?
|
222
222
|
|
223
223
|
!node.single_line?
|
224
224
|
end
|
@@ -189,7 +189,7 @@ module RuboCop
|
|
189
189
|
case node.type
|
190
190
|
when :casgn then _scope, _lhs, rhs = *node
|
191
191
|
when :op_asgn then _lhs, _op, rhs = *node
|
192
|
-
when :send
|
192
|
+
when :send, :csend then rhs = node.last_argument
|
193
193
|
else _lhs, rhs = *node
|
194
194
|
end
|
195
195
|
rhs
|
@@ -48,24 +48,32 @@ module RuboCop
|
|
48
48
|
MSG = 'Use %<style>s block forwarding.'
|
49
49
|
|
50
50
|
def self.autocorrect_incompatible_with
|
51
|
-
[Lint::AmbiguousOperator]
|
51
|
+
[Lint::AmbiguousOperator, Style::ArgumentsForwarding]
|
52
52
|
end
|
53
53
|
|
54
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
54
55
|
def on_def(node)
|
55
56
|
return if node.arguments.empty?
|
56
57
|
|
57
|
-
last_argument = node.
|
58
|
+
last_argument = node.last_argument
|
58
59
|
return if expected_block_forwarding_style?(node, last_argument)
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
invalid_syntax = false
|
62
62
|
node.each_descendant(:block_pass) do |block_pass_node|
|
63
63
|
next if block_pass_node.children.first&.sym_type? ||
|
64
64
|
last_argument.source != block_pass_node.source
|
65
65
|
|
66
|
+
if block_pass_node.each_ancestor(:block, :numblock).any?
|
67
|
+
invalid_syntax = true
|
68
|
+
next
|
69
|
+
end
|
70
|
+
|
66
71
|
register_offense(block_pass_node, node)
|
67
72
|
end
|
73
|
+
|
74
|
+
register_offense(last_argument, node) unless invalid_syntax
|
68
75
|
end
|
76
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
69
77
|
alias on_defs on_def
|
70
78
|
|
71
79
|
private
|
@@ -61,8 +61,7 @@ module RuboCop
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def allowed_method_call_on_rhs?(node)
|
64
|
-
node&.send_type? &&
|
65
|
-
(node.receiver.nil? || !literal_receiver?(node))
|
64
|
+
node&.send_type? && (node.receiver.nil? || !literal_receiver?(node))
|
66
65
|
end
|
67
66
|
|
68
67
|
# @!method literal_receiver?(node)
|
@@ -203,7 +203,7 @@ module RuboCop
|
|
203
203
|
|
204
204
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
205
205
|
def on_defined?(node)
|
206
|
-
arg = node.
|
206
|
+
arg = node.first_argument
|
207
207
|
return false unless arg.ivar_type?
|
208
208
|
|
209
209
|
method_node, method_name = find_definition(node)
|
@@ -99,7 +99,7 @@ module RuboCop
|
|
99
99
|
!(method_name.start_with?(prefix) && # cheap check to avoid allocating Regexp
|
100
100
|
method_name.match?(/^#{prefix}[^0-9]/)) ||
|
101
101
|
method_name == expected_name(method_name, prefix) ||
|
102
|
-
method_name.end_with?('=') ||
|
102
|
+
method_name.end_with?('=') ||
|
103
103
|
allowed_method?(method_name)
|
104
104
|
end
|
105
105
|
|
@@ -109,7 +109,7 @@ module RuboCop
|
|
109
109
|
else
|
110
110
|
method_name.dup
|
111
111
|
end
|
112
|
-
new_name << '?' unless method_name.end_with?('?')
|
112
|
+
new_name << '?' unless method_name.end_with?('?')
|
113
113
|
new_name
|
114
114
|
end
|
115
115
|
|
data/lib/rubocop/cop/registry.rb
CHANGED
@@ -300,7 +300,7 @@ module RuboCop
|
|
300
300
|
unless given_badge.match?(real_badge)
|
301
301
|
path = PathUtil.smart_path(source_path)
|
302
302
|
warn "#{path}: #{given_badge} has the wrong namespace - " \
|
303
|
-
"
|
303
|
+
"replace it with #{given_badge.with_department(real_badge.department)}"
|
304
304
|
end
|
305
305
|
|
306
306
|
real_badge.to_s
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
# # bad
|
24
24
|
# open(something)
|
25
25
|
# open("| #{something}")
|
26
|
+
# open("| foo")
|
26
27
|
# URI.open(something)
|
27
28
|
#
|
28
29
|
# # good
|
@@ -32,7 +33,6 @@ module RuboCop
|
|
32
33
|
#
|
33
34
|
# # good (literal strings)
|
34
35
|
# open("foo.text")
|
35
|
-
# open("| foo")
|
36
36
|
# URI.open("http://example.com")
|
37
37
|
class Open < Base
|
38
38
|
MSG = 'The use of `%<receiver>sopen` is a serious security risk.'
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
|
41
41
|
# @!method open?(node)
|
42
42
|
def_node_matcher :open?, <<~PATTERN
|
43
|
-
(send ${nil? (const {nil? cbase} :URI)} :open
|
43
|
+
(send ${nil? (const {nil? cbase} :URI)} :open $_ ...)
|
44
44
|
PATTERN
|
45
45
|
|
46
46
|
def on_send(node)
|
@@ -168,12 +168,12 @@ module RuboCop
|
|
168
168
|
|
169
169
|
def find_corresponding_def_node(node)
|
170
170
|
if access_modifier_with_symbol?(node)
|
171
|
-
method_name = node.
|
171
|
+
method_name = node.first_argument.value
|
172
172
|
node.parent.each_child_node(:def).find do |child|
|
173
173
|
child.method?(method_name)
|
174
174
|
end
|
175
175
|
else
|
176
|
-
node.
|
176
|
+
node.first_argument
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|