rubocop 1.21.0 → 1.22.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 +1 -1
- data/config/default.yml +43 -6
- data/lib/rubocop/config.rb +5 -0
- data/lib/rubocop/config_loader.rb +2 -0
- data/lib/rubocop/config_validator.rb +9 -1
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +34 -11
- data/lib/rubocop/cop/bundler/ordered_gems.rb +3 -12
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +11 -10
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +3 -12
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
- data/lib/rubocop/cop/generator.rb +14 -8
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +25 -2
- data/lib/rubocop/cop/layout/line_length.rb +7 -5
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -24
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +5 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +7 -7
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +7 -5
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +18 -5
- data/lib/rubocop/cop/lint/boolean_symbol.rb +5 -0
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +24 -1
- data/lib/rubocop/cop/lint/else_layout.rb +9 -5
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +12 -3
- data/lib/rubocop/cop/lint/interpolation_check.rb +5 -0
- data/lib/rubocop/cop/lint/loop.rb +4 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +4 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +10 -0
- data/lib/rubocop/cop/lint/raise_exception.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +5 -4
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +49 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/triple_quotes.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +8 -3
- data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/lint/useless_times.rb +3 -2
- data/lib/rubocop/cop/metrics/abc_size.rb +6 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +5 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +9 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +6 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +5 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +7 -0
- data/lib/rubocop/cop/security/io_methods.rb +49 -0
- data/lib/rubocop/cop/security/json_load.rb +8 -7
- data/lib/rubocop/cop/security/open.rb +4 -0
- data/lib/rubocop/cop/security/yaml_load.rb +4 -0
- data/lib/rubocop/cop/style/and_or.rb +4 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +13 -2
- data/lib/rubocop/cop/style/array_coercion.rb +21 -3
- data/lib/rubocop/cop/style/case_like_if.rb +5 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +9 -0
- data/lib/rubocop/cop/style/collection_compact.rb +7 -5
- data/lib/rubocop/cop/style/collection_methods.rb +6 -5
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +4 -1
- data/lib/rubocop/cop/style/date_time.rb +5 -0
- data/lib/rubocop/cop/style/double_negation.rb +15 -5
- data/lib/rubocop/cop/style/float_division.rb +10 -2
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +6 -1
- data/lib/rubocop/cop/style/global_std_stream.rb +4 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +5 -0
- data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -6
- data/lib/rubocop/cop/style/hash_transform_values.rb +4 -6
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -16
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +15 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +4 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +13 -0
- data/lib/rubocop/cop/style/module_function.rb +8 -9
- data/lib/rubocop/cop/style/mutable_constant.rb +12 -7
- data/lib/rubocop/cop/style/numbered_parameters.rb +46 -0
- data/lib/rubocop/cop/style/numbered_parameters_limit.rb +50 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
- data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
- data/lib/rubocop/cop/style/optional_arguments.rb +4 -0
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +14 -4
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -4
- data/lib/rubocop/cop/style/redundant_argument.rb +14 -7
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +4 -0
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +12 -3
- data/lib/rubocop/cop/style/redundant_freeze.rb +0 -1
- data/lib/rubocop/cop/style/redundant_self.rb +10 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +4 -3
- data/lib/rubocop/cop/style/redundant_sort.rb +47 -29
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +106 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +5 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +13 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -0
- data/lib/rubocop/cop/style/static_class.rb +4 -3
- data/lib/rubocop/cop/style/string_chars.rb +4 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +4 -0
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +3 -2
- data/lib/rubocop/cop/style/swap_values.rb +4 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +26 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +19 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +20 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -0
- data/lib/rubocop/cop/util.rb +2 -2
- data/lib/rubocop/cops_documentation_generator.rb +17 -5
- data/lib/rubocop/options.rb +126 -112
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +10 -5
@@ -10,14 +10,25 @@ module RuboCop
|
|
10
10
|
# need to be changed to use safe navigation. We have limited the cop to
|
11
11
|
# not register an offense for method chains that exceed 2 methods.
|
12
12
|
#
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# The default for `ConvertCodeThatCanStartToReturnNil` is `false`.
|
14
|
+
# When configured to `true`, this will
|
15
15
|
# check for code in the format `!foo.nil? && foo.bar`. As it is written,
|
16
16
|
# the return of this code is limited to `false` and whatever the return
|
17
17
|
# of the method is. If this is converted to safe navigation,
|
18
18
|
# `foo&.bar` can start returning `nil` as well as what the method
|
19
19
|
# returns.
|
20
20
|
#
|
21
|
+
# @safety
|
22
|
+
# Autocorrection is unsafe because if a value is `false`, the resulting
|
23
|
+
# code will have different behaviour or raise an error.
|
24
|
+
#
|
25
|
+
# [source,ruby]
|
26
|
+
# ----
|
27
|
+
# x = false
|
28
|
+
# x && x.foo # return false
|
29
|
+
# x&.foo # raises NoMethodError
|
30
|
+
# ----
|
31
|
+
#
|
21
32
|
# @example
|
22
33
|
# # bad
|
23
34
|
# foo.bar if foo
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop looks for places where an subset of an array
|
7
|
+
# is calculated based on a `Regexp` match, and suggests `grep` or
|
8
|
+
# `grep_v` instead.
|
9
|
+
#
|
10
|
+
# NOTE: `grep` and `grep_v` were optimized when used without a block
|
11
|
+
# in Ruby 3.0, but may be slower in previous versions.
|
12
|
+
# See https://bugs.ruby-lang.org/issues/17030
|
13
|
+
#
|
14
|
+
# @safety
|
15
|
+
# Autocorrection is marked as unsafe because `MatchData` will
|
16
|
+
# not be created by `grep`, but may have previously been relied
|
17
|
+
# upon after the `match?` or `=~` call.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# # bad (select or find_all)
|
21
|
+
# array.select { |x| x.match? /regexp/ }
|
22
|
+
# array.select { |x| /regexp/.match?(x) }
|
23
|
+
# array.select { |x| x =~ /regexp/ }
|
24
|
+
# array.select { |x| /regexp/ =~ x }
|
25
|
+
#
|
26
|
+
# # bad (reject)
|
27
|
+
# array.reject { |x| x.match? /regexp/ }
|
28
|
+
# array.reject { |x| /regexp/.match?(x) }
|
29
|
+
# array.reject { |x| x =~ /regexp/ }
|
30
|
+
# array.reject { |x| /regexp/ =~ x }
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# array.grep(regexp)
|
34
|
+
# array.grep_v(regexp)
|
35
|
+
class SelectByRegexp < Base
|
36
|
+
extend AutoCorrector
|
37
|
+
include RangeHelp
|
38
|
+
|
39
|
+
MSG = 'Prefer `%<replacement>s` to `%<original_method>s` with a regexp match.'
|
40
|
+
RESTRICT_ON_SEND = %i[select find_all reject].freeze
|
41
|
+
REPLACEMENTS = { select: 'grep', find_all: 'grep', reject: 'grep_v' }.freeze
|
42
|
+
REGEXP_METHODS = %i[match? =~].to_set.freeze
|
43
|
+
|
44
|
+
# @!method regexp_match?(node)
|
45
|
+
def_node_matcher :regexp_match?, <<~PATTERN
|
46
|
+
{
|
47
|
+
(block send (args (arg $_)) ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
|
48
|
+
(numblock send $1 ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
|
49
|
+
}
|
50
|
+
PATTERN
|
51
|
+
|
52
|
+
# @!method calls_lvar?(node, name)
|
53
|
+
def_node_matcher :calls_lvar?, <<~PATTERN
|
54
|
+
{
|
55
|
+
(send (lvar %1) ...)
|
56
|
+
(send ... (lvar %1))
|
57
|
+
(match-with-lvasgn regexp (lvar %1))
|
58
|
+
}
|
59
|
+
PATTERN
|
60
|
+
|
61
|
+
def on_send(node)
|
62
|
+
return unless (block_node = node.block_node)
|
63
|
+
return if block_node.body.begin_type?
|
64
|
+
return unless (regexp_method_send_node = extract_send_node(block_node))
|
65
|
+
|
66
|
+
regexp = find_regexp(regexp_method_send_node)
|
67
|
+
register_offense(node, block_node, regexp)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def register_offense(node, block_node, regexp)
|
73
|
+
replacement = REPLACEMENTS[node.method_name.to_sym]
|
74
|
+
message = format(MSG, replacement: replacement, original_method: node.method_name)
|
75
|
+
|
76
|
+
add_offense(block_node, message: message) do |corrector|
|
77
|
+
# Only correct if it can be determined what the regexp is
|
78
|
+
if regexp
|
79
|
+
range = range_between(node.loc.selector.begin_pos, block_node.loc.end.end_pos)
|
80
|
+
corrector.replace(range, "#{replacement}(#{regexp.source})")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def extract_send_node(block_node)
|
86
|
+
return unless (block_arg_name, regexp_method_send_node = regexp_match?(block_node))
|
87
|
+
|
88
|
+
block_arg_name = :"_#{block_arg_name}" if block_node.numblock_type?
|
89
|
+
return unless calls_lvar?(regexp_method_send_node, block_arg_name)
|
90
|
+
|
91
|
+
regexp_method_send_node
|
92
|
+
end
|
93
|
+
|
94
|
+
def find_regexp(node)
|
95
|
+
return node.child_nodes.first if node.match_with_lvasgn_type?
|
96
|
+
|
97
|
+
if node.receiver.lvar_type?
|
98
|
+
node.first_argument
|
99
|
+
elsif node.first_argument.lvar_type?
|
100
|
+
node.receiver
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -6,6 +6,11 @@ module RuboCop
|
|
6
6
|
# Sometimes using dig method ends up with just a single
|
7
7
|
# argument. In such cases, dig should be replaced with [].
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
11
|
+
# is an `Enumerable` or does not have a nonstandard implementation
|
12
|
+
# of `dig`.
|
13
|
+
#
|
9
14
|
# @example
|
10
15
|
# # bad
|
11
16
|
# { key: 'value' }.dig(:key)
|
@@ -6,6 +6,19 @@ module RuboCop
|
|
6
6
|
# This cop checks that arrays are sliced with endless ranges instead of
|
7
7
|
# `ary[start..-1]` on Ruby 2.6+.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because `x..-1` and `x..` are only guaranteed to
|
11
|
+
# be equivalent for `Array#[]`, and the cop cannot determine what class
|
12
|
+
# the receiver is.
|
13
|
+
#
|
14
|
+
# For example:
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
17
|
+
# sum = proc { |ary| ary.sum }
|
18
|
+
# sum[-3..-1] # => -6
|
19
|
+
# sum[-3..] # Hangs forever
|
20
|
+
# ----
|
21
|
+
#
|
9
22
|
# @example
|
10
23
|
# # bad
|
11
24
|
# items[1..-1]
|
@@ -9,6 +9,10 @@ module RuboCop
|
|
9
9
|
# will add a require statement to the top of the file if
|
10
10
|
# enabled by RequireEnglish config.
|
11
11
|
#
|
12
|
+
# @safety
|
13
|
+
# Autocorrection is marked as unsafe because if `RequireEnglish` is not
|
14
|
+
# true, replacing perl-style variables with english variables will break.
|
15
|
+
#
|
12
16
|
# @example EnforcedStyle: use_english_names (default)
|
13
17
|
# # good
|
14
18
|
# require 'English' # or this could be in another file.
|
@@ -7,9 +7,10 @@ module RuboCop
|
|
7
7
|
# replaced with a module. Classes should be used only when it makes sense to create
|
8
8
|
# instances out of them.
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# @safety
|
11
|
+
# This cop is unsafe, because it is possible that this class is a parent
|
12
|
+
# for some other subclass, monkey-patched with instance methods or
|
13
|
+
# a dummy instance is instantiated from it somewhere.
|
13
14
|
#
|
14
15
|
# @example
|
15
16
|
# # bad
|
@@ -5,8 +5,10 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for uses of `String#split` with empty string or regexp literal argument.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# @safety
|
9
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
10
|
+
# is actually a string. If another class has a `split` method with
|
11
|
+
# different behaviour, it would be registered as a false positive.
|
10
12
|
#
|
11
13
|
# @example
|
12
14
|
# # bad
|
@@ -23,6 +23,10 @@ module RuboCop
|
|
23
23
|
# This is useful when the receiver is some expression that returns string like `Pathname`
|
24
24
|
# instead of a string literal.
|
25
25
|
#
|
26
|
+
# @safety
|
27
|
+
# This cop is unsafe in `aggressive` mode, as it cannot be guaranteed that
|
28
|
+
# the receiver is actually a string, which can result in a false positive.
|
29
|
+
#
|
26
30
|
# @example Mode: aggressive (default)
|
27
31
|
# # bad
|
28
32
|
# email_with_name = user.name + ' <' + user.email + '>'
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
6
6
|
# This cop checks for the use of strings as keys in hashes. The use of
|
7
7
|
# symbols is preferred instead.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because while symbols are preferred for hash keys,
|
11
|
+
# there are instances when string keys are required.
|
12
|
+
#
|
9
13
|
# @example
|
10
14
|
# # bad
|
11
15
|
# { 'one' => 1, 'two' => 2, 'three' => 3 }
|
@@ -5,8 +5,9 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# This cop checks for inheritance from Struct.new.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# @safety
|
9
|
+
# Auto-correction is unsafe because it will change the inheritance
|
10
|
+
# tree (e.g. return value of `Module#ancestors`) of the constant.
|
10
11
|
#
|
11
12
|
# @example
|
12
13
|
# # bad
|
@@ -4,8 +4,10 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# This cop enforces the use of shorthand-style swapping of 2 variables.
|
7
|
-
#
|
8
|
-
#
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# Autocorrection is unsafe, because the temporary variable used to
|
10
|
+
# swap variables will be removed, but may be referred to elsewhere.
|
9
11
|
#
|
10
12
|
# @example
|
11
13
|
# # bad
|
@@ -8,6 +8,32 @@ module RuboCop
|
|
8
8
|
# If you prefer a style that allows block for method with arguments,
|
9
9
|
# please set `true` to `AllowMethodsWithArguments`.
|
10
10
|
#
|
11
|
+
# @safety
|
12
|
+
# This cop is unsafe because `proc`s and blocks work differently
|
13
|
+
# when additional arguments are passed in. A block will silently
|
14
|
+
# ignore additional arguments, but a `proc` will raise
|
15
|
+
# an `ArgumentError`.
|
16
|
+
#
|
17
|
+
# For example:
|
18
|
+
#
|
19
|
+
# [source,ruby]
|
20
|
+
# ----
|
21
|
+
# class Foo
|
22
|
+
# def bar
|
23
|
+
# :bar
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# def call(options = {}, &block)
|
28
|
+
# block.call(Foo.new, options)
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# call { |x| x.bar }
|
32
|
+
# #=> :bar
|
33
|
+
# call(&:bar)
|
34
|
+
# # ArgumentError: wrong number of arguments (given 1, expected 0)
|
35
|
+
# ----
|
36
|
+
#
|
11
37
|
# @example
|
12
38
|
# # bad
|
13
39
|
# something.map { |s| s.upcase }
|
@@ -8,6 +8,25 @@ module RuboCop
|
|
8
8
|
# that comma to be present. Blocks with more than one argument never
|
9
9
|
# require a trailing comma.
|
10
10
|
#
|
11
|
+
# @safety
|
12
|
+
# This cop is unsafe because a trailing comma can indicate there are
|
13
|
+
# more parameters that are not used.
|
14
|
+
#
|
15
|
+
# For example:
|
16
|
+
# [source,ruby]
|
17
|
+
# ----
|
18
|
+
# # with a trailing comma
|
19
|
+
# {foo: 1, bar: 2, baz: 3}.map {|key,| key }
|
20
|
+
# #=> [:foo, :bar, :baz]
|
21
|
+
#
|
22
|
+
# # without a trailing comma
|
23
|
+
# {foo: 1, bar: 2, baz: 3}.map {|key| key }
|
24
|
+
# #=> [[:foo, 1], [:bar, 2], [:baz, 3]]
|
25
|
+
# ----
|
26
|
+
#
|
27
|
+
# This can be fixed by replacing the trailing comma with a placeholder
|
28
|
+
# argument (such as `|key, _value|`).
|
29
|
+
#
|
11
30
|
# @example
|
12
31
|
# # bad
|
13
32
|
# add { |foo, bar,| foo + bar }
|
@@ -7,6 +7,26 @@ module RuboCop
|
|
7
7
|
# i.e. comparison operations where the order of expression is reversed.
|
8
8
|
# eg. `5 == x`
|
9
9
|
#
|
10
|
+
# @safety
|
11
|
+
# This cop is unsafe because comparison operators can be defined
|
12
|
+
# differently on different classes, and are not guaranteed to
|
13
|
+
# have the same result if reversed.
|
14
|
+
#
|
15
|
+
# For example:
|
16
|
+
#
|
17
|
+
# [source,ruby]
|
18
|
+
# ----
|
19
|
+
# class MyKlass
|
20
|
+
# def ==(other)
|
21
|
+
# true
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# obj = MyKlass.new
|
26
|
+
# obj == 'string' #=> true
|
27
|
+
# 'string' == obj #=> false
|
28
|
+
# ----
|
29
|
+
#
|
10
30
|
# @example EnforcedStyle: forbid_for_all_comparison_operators (default)
|
11
31
|
# # bad
|
12
32
|
# 99 == foo
|
@@ -9,6 +9,12 @@ module RuboCop
|
|
9
9
|
# receiver.length < 1 and receiver.size == 0 that can be
|
10
10
|
# replaced by receiver.empty? and !receiver.empty?.
|
11
11
|
#
|
12
|
+
# @safety
|
13
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
14
|
+
# has an `empty?` method that is defined in terms of `length`. If there
|
15
|
+
# is a non-standard class that redefines `length` or `empty?`, the cop
|
16
|
+
# may register a false positive.
|
17
|
+
#
|
12
18
|
# @example
|
13
19
|
# # bad
|
14
20
|
# [1, 2, 3].length == 0
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -129,8 +129,8 @@ module RuboCop
|
|
129
129
|
node1.respond_to?(:loc) && node2.respond_to?(:loc) && node1.loc.line == node2.loc.line
|
130
130
|
end
|
131
131
|
|
132
|
-
def indent(node)
|
133
|
-
' ' * node.loc.column
|
132
|
+
def indent(node, offset: 0)
|
133
|
+
' ' * (node.loc.column + offset)
|
134
134
|
end
|
135
135
|
|
136
136
|
def to_supported_styles(enforced_style)
|
@@ -33,11 +33,12 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
33
33
|
cops.with_department(department).sort!
|
34
34
|
end
|
35
35
|
|
36
|
-
def cops_body(cop, description, examples_objects, pars)
|
36
|
+
def cops_body(cop, description, examples_objects, safety_objects, pars) # rubocop:disable Metrics/AbcSize
|
37
37
|
content = h2(cop.cop_name)
|
38
38
|
content << required_ruby_version(cop)
|
39
39
|
content << properties(cop)
|
40
40
|
content << "#{description}\n"
|
41
|
+
content << safety_object(safety_objects) if safety_objects.any? { |s| !s.text.blank? }
|
41
42
|
content << examples(examples_objects) if examples_objects.count.positive?
|
42
43
|
content << configurations(pars)
|
43
44
|
content << references(cop)
|
@@ -52,6 +53,16 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
56
|
+
def safety_object(safety_object_objects)
|
57
|
+
safety_object_objects.each_with_object(h3('Safety').dup) do |safety_object, content|
|
58
|
+
next if safety_object.text.blank?
|
59
|
+
|
60
|
+
content << "\n" unless content.end_with?("\n\n")
|
61
|
+
content << safety_object.text
|
62
|
+
content << "\n"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
55
66
|
def required_ruby_version(cop)
|
56
67
|
return '' unless cop.respond_to?(:required_minimum_ruby_version)
|
57
68
|
|
@@ -61,8 +72,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
61
72
|
# rubocop:disable Metrics/MethodLength
|
62
73
|
def properties(cop)
|
63
74
|
header = [
|
64
|
-
'Enabled by default', 'Safe', 'Supports autocorrection', '
|
65
|
-
'
|
75
|
+
'Enabled by default', 'Safe', 'Supports autocorrection', 'Version Added',
|
76
|
+
'Version Changed'
|
66
77
|
]
|
67
78
|
autocorrect = if cop.support_autocorrect?
|
68
79
|
"Yes#{' (Unsafe)' unless cop.new(config).safe_autocorrect?}"
|
@@ -217,12 +228,13 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
217
228
|
]
|
218
229
|
pars = cop_config.reject { |k| non_display_keys.include? k }
|
219
230
|
description = 'No documentation'
|
220
|
-
examples_object = []
|
231
|
+
examples_object = safety_object = []
|
221
232
|
cop_code(cop) do |code_object|
|
222
233
|
description = code_object.docstring unless code_object.docstring.blank?
|
223
234
|
examples_object = code_object.tags('example')
|
235
|
+
safety_object = code_object.tags('safety')
|
224
236
|
end
|
225
|
-
cops_body(cop, description, examples_object, pars)
|
237
|
+
cops_body(cop, description, examples_object, safety_object, pars)
|
226
238
|
end
|
227
239
|
|
228
240
|
def cop_code(cop)
|