rubocop 1.7.0 → 1.10.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/LICENSE.txt +1 -1
- data/README.md +4 -3
- data/config/default.yml +137 -31
- data/config/obsoletion.yml +4 -0
- data/lib/rubocop.rb +14 -1
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +5 -4
- data/lib/rubocop/comment_config.rb +6 -6
- data/lib/rubocop/config.rb +5 -2
- data/lib/rubocop/config_loader.rb +7 -14
- data/lib/rubocop/config_store.rb +12 -1
- data/lib/rubocop/cop/base.rb +2 -1
- data/lib/rubocop/cop/exclude_limit.rb +26 -0
- data/lib/rubocop/cop/gemspec/date_assignment.rb +56 -0
- data/lib/rubocop/cop/generator.rb +1 -3
- data/lib/rubocop/cop/internal_affairs.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +68 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +89 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +61 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +64 -0
- data/lib/rubocop/cop/layout/class_structure.rb +7 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +38 -18
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +16 -2
- data/lib/rubocop/cop/layout/line_length.rb +2 -1
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +26 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/space_before_brackets.rb +19 -16
- data/lib/rubocop/cop/lint/debugger.rb +58 -14
- data/lib/rubocop/cop/lint/deprecated_constants.rb +80 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +13 -4
- data/lib/rubocop/cop/lint/duplicate_require.rb +2 -2
- data/lib/rubocop/cop/lint/else_layout.rb +1 -1
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +44 -0
- data/lib/rubocop/cop/lint/multiple_comparison.rb +4 -4
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -6
- data/lib/rubocop/cop/lint/number_conversion.rb +41 -6
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +47 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +39 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +50 -0
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +5 -3
- data/lib/rubocop/cop/lint/symbol_conversion.rb +103 -0
- data/lib/rubocop/cop/lint/triple_quotes.rb +71 -0
- data/lib/rubocop/cop/message_annotator.rb +4 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
- data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
- data/lib/rubocop/cop/mixin/allowed_identifiers.rb +18 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +5 -0
- data/lib/rubocop/cop/mixin/code_length.rb +3 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -11
- data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +3 -1
- data/lib/rubocop/cop/mixin/preferred_delimiters.rb +2 -2
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +5 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +38 -5
- data/lib/rubocop/cop/naming/variable_name.rb +2 -0
- data/lib/rubocop/cop/naming/variable_number.rb +2 -9
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/severity.rb +3 -3
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/constant_visibility.rb +27 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +49 -9
- data/lib/rubocop/cop/style/double_negation.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +6 -2
- data/lib/rubocop/cop/style/endless_method.rb +102 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +138 -49
- data/lib/rubocop/cop/style/explicit_block_argument.rb +11 -1
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -7
- data/lib/rubocop/cop/style/float_division.rb +3 -0
- data/lib/rubocop/cop/style/format_string_token.rb +18 -2
- data/lib/rubocop/cop/style/hash_conversion.rb +81 -0
- data/lib/rubocop/cop/style/hash_like_case.rb +2 -1
- data/lib/rubocop/cop/style/if_inside_else.rb +22 -10
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +120 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +4 -0
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +4 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +3 -0
- data/lib/rubocop/cop/style/non_nil_check.rb +23 -13
- data/lib/rubocop/cop/style/numeric_literals.rb +6 -9
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +3 -2
- data/lib/rubocop/cop/style/redundant_return.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +32 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +29 -5
- data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +2 -4
- data/lib/rubocop/formatter/git_hub_actions_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/magic_comment.rb +30 -1
- data/lib/rubocop/options.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +5 -2
- data/lib/rubocop/runner.rb +1 -0
- data/lib/rubocop/target_ruby.rb +47 -11
- data/lib/rubocop/version.rb +2 -2
- metadata +24 -7
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for deprecated constants.
|
7
|
+
#
|
8
|
+
# It has `DeprecatedConstants` config. If there is an alternative method, you can set
|
9
|
+
# alternative value as `Alternative`. And you can set the deprecated version as
|
10
|
+
# `DeprecatedVersion`. These options can be omitted if they are not needed.
|
11
|
+
#
|
12
|
+
# DeprecatedConstants:
|
13
|
+
# 'DEPRECATED_CONSTANT':
|
14
|
+
# Alternative: 'alternative_value'
|
15
|
+
# DeprecatedVersion: 'deprecated_version'
|
16
|
+
#
|
17
|
+
# By default, `NIL`, `TRUE`, `FALSE` and `Random::DEFAULT` are configured.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# NIL
|
23
|
+
# TRUE
|
24
|
+
# FALSE
|
25
|
+
# Random::DEFAULT # Return value of Ruby 2 is `Random` instance, Ruby 3.0 is `Random` class.
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# nil
|
29
|
+
# true
|
30
|
+
# false
|
31
|
+
# Random.new # `::DEFAULT` has been deprecated in Ruby 3, `.new` is compatible with Ruby 2.
|
32
|
+
#
|
33
|
+
class DeprecatedConstants < Base
|
34
|
+
extend AutoCorrector
|
35
|
+
|
36
|
+
SUGGEST_GOOD_MSG = 'Use `%<good>s` instead of `%<bad>s`%<deprecated_message>s.'
|
37
|
+
DO_NOT_USE_MSG = 'Do not use `%<bad>s`%<deprecated_message>s.'
|
38
|
+
|
39
|
+
def on_const(node)
|
40
|
+
# FIXME: Workaround for "`undefined method `expression' for nil:NilClass`" when processing
|
41
|
+
# `__ENCODING__`. It is better to be able to work without this condition.
|
42
|
+
# Maybe further investigation of RuboCop AST will lead to an essential solution.
|
43
|
+
return unless node.loc
|
44
|
+
|
45
|
+
constant = node.absolute? ? consntant_name(node, node.short_name.to_s) : node.source
|
46
|
+
return unless (deprecated_constant = deprecated_constants[constant])
|
47
|
+
|
48
|
+
alternative = deprecated_constant['Alternative']
|
49
|
+
version = deprecated_constant['DeprecatedVersion']
|
50
|
+
|
51
|
+
add_offense(node, message: message(alternative, node.source, version)) do |corrector|
|
52
|
+
corrector.replace(node, alternative)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def consntant_name(node, nested_constant_name)
|
59
|
+
return nested_constant_name unless node.namespace.const_type?
|
60
|
+
|
61
|
+
consntant_name(node.namespace, "#{node.namespace.short_name}::#{nested_constant_name}")
|
62
|
+
end
|
63
|
+
|
64
|
+
def message(good, bad, deprecated_version)
|
65
|
+
deprecated_message = ", deprecated since Ruby #{deprecated_version}" if deprecated_version
|
66
|
+
|
67
|
+
if good
|
68
|
+
format(SUGGEST_GOOD_MSG, good: good, bad: bad, deprecated_message: deprecated_message)
|
69
|
+
else
|
70
|
+
format(DO_NOT_USE_MSG, bad: bad, deprecated_message: deprecated_message)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def deprecated_constants
|
75
|
+
cop_config.fetch('DeprecatedConstants', {})
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -44,6 +44,8 @@ module RuboCop
|
|
44
44
|
MSG = 'Use `%<constant>s.%<method>s(%<replacement_args>s)`' \
|
45
45
|
' instead of `%<original>s`.'
|
46
46
|
|
47
|
+
NO_ARG_ALGORITHM = %w[BF DES IDEA RC4].freeze
|
48
|
+
|
47
49
|
def_node_matcher :algorithm_const, <<~PATTERN
|
48
50
|
(send
|
49
51
|
$(const
|
@@ -104,7 +106,7 @@ module RuboCop
|
|
104
106
|
def algorithm_name(node)
|
105
107
|
name = node.loc.name.source
|
106
108
|
|
107
|
-
if openssl_class(node) == 'OpenSSL::Cipher'
|
109
|
+
if openssl_class(node) == 'OpenSSL::Cipher' && !NO_ARG_ALGORITHM.include?(name)
|
108
110
|
name.scan(/.{3}/).join('-')
|
109
111
|
else
|
110
112
|
name
|
@@ -124,16 +126,23 @@ module RuboCop
|
|
124
126
|
algorithm_name = algorithm_name(algorithm_constant)
|
125
127
|
|
126
128
|
if openssl_class(algorithm_constant) == 'OpenSSL::Cipher'
|
127
|
-
build_cipher_arguments(node, algorithm_name)
|
129
|
+
build_cipher_arguments(node, algorithm_name, node.arguments.empty?)
|
128
130
|
else
|
129
131
|
(["'#{algorithm_name}'"] + node.arguments.map(&:source)).join(', ')
|
130
132
|
end
|
131
133
|
end
|
132
134
|
|
133
|
-
def build_cipher_arguments(node, algorithm_name)
|
135
|
+
def build_cipher_arguments(node, algorithm_name, no_arguments)
|
134
136
|
algorithm_parts = algorithm_name.downcase.split('-')
|
135
137
|
size_and_mode = sanitize_arguments(node.arguments).map(&:downcase)
|
136
|
-
|
138
|
+
|
139
|
+
if NO_ARG_ALGORITHM.include?(algorithm_parts.first.upcase) && no_arguments
|
140
|
+
"'#{algorithm_parts.first}'"
|
141
|
+
else
|
142
|
+
mode = 'cbc' unless size_and_mode == ['cbc']
|
143
|
+
|
144
|
+
"'#{(algorithm_parts + size_and_mode + [mode]).compact.take(3).join('-')}'"
|
145
|
+
end
|
137
146
|
end
|
138
147
|
end
|
139
148
|
end
|
@@ -21,11 +21,11 @@ module RuboCop
|
|
21
21
|
#
|
22
22
|
class DuplicateRequire < Base
|
23
23
|
MSG = 'Duplicate `%<method>s` detected.'
|
24
|
-
REQUIRE_METHODS = %i[require require_relative].freeze
|
24
|
+
REQUIRE_METHODS = Set.new(%i[require require_relative]).freeze
|
25
25
|
RESTRICT_ON_SEND = REQUIRE_METHODS
|
26
26
|
|
27
27
|
def_node_matcher :require_call?, <<~PATTERN
|
28
|
-
(send {nil? (const _ :Kernel)}
|
28
|
+
(send {nil? (const _ :Kernel)} %REQUIRE_METHODS _)
|
29
29
|
PATTERN
|
30
30
|
|
31
31
|
def on_new_investigation
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks uses of lambda without a literal block.
|
7
|
+
# It emulates the following warning in Ruby 3.0:
|
8
|
+
#
|
9
|
+
# % ruby -vwe 'lambda(&proc {})'
|
10
|
+
# ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
|
11
|
+
# -e:1: warning: lambda without a literal block is deprecated; use the proc without
|
12
|
+
# lambda instead
|
13
|
+
#
|
14
|
+
# This way, proc object is never converted to lambda.
|
15
|
+
# Auto-correction replaces with compatible proc argument.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# # bad
|
20
|
+
# lambda(&proc { do_something })
|
21
|
+
# lambda(&Proc.new { do_something })
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# proc { do_something }
|
25
|
+
# Proc.new { do_something }
|
26
|
+
# lambda { do_something } # If you use lambda.
|
27
|
+
#
|
28
|
+
class LambdaWithoutLiteralBlock < Base
|
29
|
+
extend AutoCorrector
|
30
|
+
|
31
|
+
MSG = 'lambda without a literal block is deprecated; use the proc without lambda instead.'
|
32
|
+
RESTRICT_ON_SEND = %i[lambda].freeze
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
return if node.parent&.block_type? || !node.first_argument
|
36
|
+
|
37
|
+
add_offense(node) do |corrector|
|
38
|
+
corrector.replace(node, node.first_argument.source.delete('&'))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -11,14 +11,10 @@ module RuboCop
|
|
11
11
|
# @example
|
12
12
|
#
|
13
13
|
# # bad
|
14
|
-
#
|
15
14
|
# x < y < z
|
16
15
|
# 10 <= x <= 20
|
17
16
|
#
|
18
|
-
# @example
|
19
|
-
#
|
20
17
|
# # good
|
21
|
-
#
|
22
18
|
# x < y && y < z
|
23
19
|
# 10 <= x && x <= 20
|
24
20
|
class MultipleComparison < Base
|
@@ -26,6 +22,7 @@ module RuboCop
|
|
26
22
|
|
27
23
|
MSG = 'Use the `&&` operator to compare multiple values.'
|
28
24
|
COMPARISON_METHODS = %i[< > <= >=].freeze
|
25
|
+
SET_OPERATION_OPERATORS = %i[& | ^].freeze
|
29
26
|
RESTRICT_ON_SEND = COMPARISON_METHODS
|
30
27
|
|
31
28
|
def_node_matcher :multiple_compare?, <<~PATTERN
|
@@ -34,6 +31,9 @@ module RuboCop
|
|
34
31
|
|
35
32
|
def on_send(node)
|
36
33
|
return unless (center = multiple_compare?(node))
|
34
|
+
# It allows multiple comparison using `&`, `|`, and `^` set operation operators.
|
35
|
+
# e.g. `x >= y & y < z`
|
36
|
+
return if center.send_type? && SET_OPERATION_OPERATORS.include?(center.method_name)
|
37
37
|
|
38
38
|
add_offense(node) do |corrector|
|
39
39
|
new_center = "#{center.source} && #{center.source}"
|
@@ -11,6 +11,11 @@ module RuboCop
|
|
11
11
|
# that are hard to debug. To ensure this doesn't happen,
|
12
12
|
# always sort the list.
|
13
13
|
#
|
14
|
+
# `Dir.glob` and `Dir[]` sort globbed results by default in Ruby 3.0.
|
15
|
+
# So all bad cases are acceptable when Ruby 3.0 or higher are used.
|
16
|
+
#
|
17
|
+
# This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.
|
18
|
+
#
|
14
19
|
# @example
|
15
20
|
#
|
16
21
|
# # bad
|
@@ -23,8 +28,6 @@ module RuboCop
|
|
23
28
|
# require file
|
24
29
|
# end
|
25
30
|
#
|
26
|
-
# @example
|
27
|
-
#
|
28
31
|
# # bad
|
29
32
|
# Dir.glob(Rails.root.join(__dir__, 'test', '*.rb')) do |file|
|
30
33
|
# require file
|
@@ -35,28 +38,28 @@ module RuboCop
|
|
35
38
|
# require file
|
36
39
|
# end
|
37
40
|
#
|
38
|
-
# @example
|
39
|
-
#
|
40
41
|
# # bad
|
41
42
|
# Dir['./lib/**/*.rb'].each(&method(:require))
|
42
43
|
#
|
43
44
|
# # good
|
44
45
|
# Dir['./lib/**/*.rb'].sort.each(&method(:require))
|
45
46
|
#
|
46
|
-
# @example
|
47
|
-
#
|
48
47
|
# # bad
|
49
48
|
# Dir.glob(Rails.root.join('test', '*.rb'), &method(:require))
|
50
49
|
#
|
51
50
|
# # good
|
52
51
|
# Dir.glob(Rails.root.join('test', '*.rb')).sort.each(&method(:require))
|
53
52
|
#
|
53
|
+
# # good - Respect intent if `sort` keyword option is specified in Ruby 3.0 or higher.
|
54
|
+
# Dir.glob(Rails.root.join(__dir__, 'test', '*.rb'), sort: false).each(&method(:require))
|
55
|
+
#
|
54
56
|
class NonDeterministicRequireOrder < Base
|
55
57
|
extend AutoCorrector
|
56
58
|
|
57
59
|
MSG = 'Sort files before requiring them.'
|
58
60
|
|
59
61
|
def on_block(node)
|
62
|
+
return if target_ruby_version >= 3.0
|
60
63
|
return unless node.body
|
61
64
|
return unless unsorted_dir_loop?(node.send_node)
|
62
65
|
|
@@ -70,6 +73,7 @@ module RuboCop
|
|
70
73
|
end
|
71
74
|
|
72
75
|
def on_block_pass(node)
|
76
|
+
return if target_ruby_version >= 3.0
|
73
77
|
return unless method_require?(node)
|
74
78
|
return unless unsorted_dir_pass?(node.parent)
|
75
79
|
|
@@ -25,12 +25,18 @@ module RuboCop
|
|
25
25
|
# '10'.to_i
|
26
26
|
# '10.2'.to_f
|
27
27
|
# '10'.to_c
|
28
|
+
# ['1', '2', '3'].map(&:to_i)
|
29
|
+
# foo.try(:to_f)
|
30
|
+
# bar.send(:to_c)
|
28
31
|
#
|
29
32
|
# # good
|
30
33
|
#
|
31
34
|
# Integer('10', 10)
|
32
35
|
# Float('10.2')
|
33
36
|
# Complex('10')
|
37
|
+
# ['1', '2', '3'].map { |i| Integer(i, 10) }
|
38
|
+
# foo.try { |i| Float(i) }
|
39
|
+
# bar.send { |i| Complex(i) }
|
34
40
|
#
|
35
41
|
# @example IgnoredMethods: [minutes]
|
36
42
|
#
|
@@ -52,22 +58,33 @@ module RuboCop
|
|
52
58
|
}.freeze
|
53
59
|
MSG = 'Replace unsafe number conversion with number '\
|
54
60
|
'class parsing, instead of using '\
|
55
|
-
'%<
|
61
|
+
'%<current>s, use stricter '\
|
56
62
|
'%<corrected_method>s.'
|
57
|
-
|
63
|
+
METHODS = CONVERSION_METHOD_CLASS_MAPPING.keys.map(&:inspect).join(' ')
|
58
64
|
|
59
65
|
def_node_matcher :to_method, <<~PATTERN
|
60
|
-
(send $_ ${
|
66
|
+
(send $_ ${#{METHODS}})
|
67
|
+
PATTERN
|
68
|
+
|
69
|
+
def_node_matcher :to_method_symbol, <<~PATTERN
|
70
|
+
{(send _ $_ ${(sym ${#{METHODS}})} ...)
|
71
|
+
(send _ $_ ${(block_pass (sym ${#{METHODS}}))} ...)}
|
61
72
|
PATTERN
|
62
73
|
|
63
74
|
def on_send(node)
|
75
|
+
handle_conversion_method(node)
|
76
|
+
handle_as_symbol(node)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def handle_conversion_method(node)
|
64
82
|
to_method(node) do |receiver, to_method|
|
65
83
|
next if receiver.nil? || ignore_receiver?(receiver)
|
66
84
|
|
67
85
|
message = format(
|
68
86
|
MSG,
|
69
|
-
|
70
|
-
to_method: to_method,
|
87
|
+
current: "#{receiver.source}.#{to_method}",
|
71
88
|
corrected_method: correct_method(node, receiver)
|
72
89
|
)
|
73
90
|
add_offense(node, message: message) do |corrector|
|
@@ -76,13 +93,31 @@ module RuboCop
|
|
76
93
|
end
|
77
94
|
end
|
78
95
|
|
79
|
-
|
96
|
+
def handle_as_symbol(node)
|
97
|
+
to_method_symbol(node) do |receiver, sym_node, to_method|
|
98
|
+
next if receiver.nil?
|
99
|
+
|
100
|
+
message = format(
|
101
|
+
MSG,
|
102
|
+
current: sym_node.source,
|
103
|
+
corrected_method: correct_sym_method(to_method)
|
104
|
+
)
|
105
|
+
add_offense(node, message: message) do |corrector|
|
106
|
+
corrector.replace(sym_node, correct_sym_method(to_method))
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
80
110
|
|
81
111
|
def correct_method(node, receiver)
|
82
112
|
format(CONVERSION_METHOD_CLASS_MAPPING[node.method_name],
|
83
113
|
number_object: receiver.source)
|
84
114
|
end
|
85
115
|
|
116
|
+
def correct_sym_method(to_method)
|
117
|
+
body = format(CONVERSION_METHOD_CLASS_MAPPING[to_method], number_object: 'i')
|
118
|
+
"{ |i| #{body} }"
|
119
|
+
end
|
120
|
+
|
86
121
|
def ignore_receiver?(receiver)
|
87
122
|
if receiver.send_type? && ignored_method?(receiver.method_name)
|
88
123
|
true
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for uses of numbered parameter assignment.
|
7
|
+
# It emulates the following warning in Ruby 2.7:
|
8
|
+
#
|
9
|
+
# % ruby -ve '_1 = :value'
|
10
|
+
# ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]
|
11
|
+
# -e:1: warning: `_1' is reserved for numbered parameter; consider another name
|
12
|
+
#
|
13
|
+
# Assiging to numbered parameter (from `_1` to `_9`) cause an error in Ruby 3.0.
|
14
|
+
#
|
15
|
+
# % ruby -ve '_1 = :value'
|
16
|
+
# ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
|
17
|
+
# -e:1: _1 is reserved for numbered parameter
|
18
|
+
#
|
19
|
+
# NOTE: The parametered parameters are from `_1` to `_9`. This cop checks `_0`, and over `_10`
|
20
|
+
# as well to prevent confusion.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# _1 = :value
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# non_numbered_parameter_name = :value
|
29
|
+
#
|
30
|
+
class NumberedParameterAssignment < Base
|
31
|
+
NUM_PARAM_MSG = '`_%<number>s` is reserved for numbered parameter; consider another name.'
|
32
|
+
LVAR_MSG = '`_%<number>s` is similar to numbered parameter; consider another name.'
|
33
|
+
NUMBERED_PARAMETER_RANGE = (1..9).freeze
|
34
|
+
|
35
|
+
def on_lvasgn(node)
|
36
|
+
lhs, _rhs = *node
|
37
|
+
return unless /\A_(\d+)\z/ =~ lhs
|
38
|
+
|
39
|
+
number = Regexp.last_match(1).to_i
|
40
|
+
template = NUMBERED_PARAMETER_RANGE.include?(number) ? NUM_PARAM_MSG : LVAR_MSG
|
41
|
+
|
42
|
+
add_offense(node, message: format(template, number: number))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for unintended or-assignment to a constant.
|
7
|
+
#
|
8
|
+
# Constants should always be assigned in the same location. And its value
|
9
|
+
# should always be the same. If constants are assigned in multiple
|
10
|
+
# locations, the result may vary depending on the order of `require`.
|
11
|
+
#
|
12
|
+
# Also, if you already have such an implementation, auto-correction may
|
13
|
+
# change the result.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# CONST ||= 1
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# CONST = 1
|
22
|
+
#
|
23
|
+
class OrAssignmentToConstant < Base
|
24
|
+
extend AutoCorrector
|
25
|
+
|
26
|
+
MSG = 'Avoid using or-assignment with constants.'
|
27
|
+
|
28
|
+
def on_or_asgn(node)
|
29
|
+
lhs, _rhs = *node
|
30
|
+
return unless lhs&.casgn_type?
|
31
|
+
|
32
|
+
add_offense(node.loc.operator) do |corrector|
|
33
|
+
corrector.replace(node.loc.operator, '=')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|