rubocop 0.45.0 → 0.46.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +17 -0
- data/config/enabled.yml +29 -2
- data/lib/rubocop.rb +6 -1
- data/lib/rubocop/config.rb +0 -10
- data/lib/rubocop/config_loader.rb +21 -9
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +69 -0
- data/lib/rubocop/cop/bundler/ordered_gems.rb +54 -0
- data/lib/rubocop/cop/cop.rb +1 -0
- data/lib/rubocop/cop/lint/debugger.rb +9 -1
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +5 -6
- data/lib/rubocop/cop/lint/eval.rb +3 -7
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +6 -4
- data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +13 -4
- data/lib/rubocop/cop/lint/useless_comparison.rb +5 -9
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
- data/lib/rubocop/cop/metrics/line_length.rb +16 -3
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +9 -9
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +14 -7
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +92 -20
- data/lib/rubocop/cop/performance/compare_with_block.rb +61 -0
- data/lib/rubocop/cop/performance/count.rb +21 -57
- data/lib/rubocop/cop/performance/detect.rb +15 -15
- data/lib/rubocop/cop/performance/flat_map.rb +23 -35
- data/lib/rubocop/cop/performance/sample.rb +84 -82
- data/lib/rubocop/cop/performance/string_replacement.rb +18 -43
- data/lib/rubocop/cop/rails/enum_uniqueness.rb +71 -0
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
- data/lib/rubocop/cop/rails/output.rb +8 -12
- data/lib/rubocop/cop/rails/read_write_attribute.rb +10 -6
- data/lib/rubocop/cop/rails/request_referer.rb +8 -9
- data/lib/rubocop/cop/rails/scope_args.rb +5 -11
- data/lib/rubocop/cop/style/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/array_join.rb +4 -8
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/case_equality.rb +3 -3
- data/lib/rubocop/cop/style/character_literal.rb +2 -4
- data/lib/rubocop/cop/style/class_check.rb +6 -6
- data/lib/rubocop/cop/style/colon_method_call.rb +6 -6
- data/lib/rubocop/cop/style/each_with_object.rb +13 -17
- data/lib/rubocop/cop/style/empty_literal.rb +46 -36
- data/lib/rubocop/cop/style/empty_method.rb +96 -0
- data/lib/rubocop/cop/style/even_odd.rb +19 -50
- data/lib/rubocop/cop/style/hash_syntax.rb +4 -1
- data/lib/rubocop/cop/style/lambda.rb +8 -18
- data/lib/rubocop/cop/style/module_function.rb +14 -11
- data/lib/rubocop/cop/style/nil_comparison.rb +4 -7
- data/lib/rubocop/cop/style/non_nil_check.rb +18 -36
- data/lib/rubocop/cop/style/numeric_predicate.rb +9 -10
- data/lib/rubocop/cop/style/op_method.rb +7 -9
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +5 -9
- data/lib/rubocop/cop/style/redundant_freeze.rb +6 -7
- data/lib/rubocop/cop/style/send.rb +6 -3
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +22 -43
- data/lib/rubocop/cop/style/ternary_parentheses.rb +67 -18
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +2 -0
- data/lib/rubocop/cop/variable_force/locatable.rb +8 -6
- data/lib/rubocop/cop/variable_force/reference.rb +2 -0
- data/lib/rubocop/formatter/base_formatter.rb +4 -8
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +6 -0
- data/lib/rubocop/node_pattern.rb +7 -5
- data/lib/rubocop/processed_source.rb +1 -0
- data/lib/rubocop/rspec/cop_helper.rb +4 -0
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +7 -3
- data/lib/rubocop/cop/performance/sort_with_block.rb +0 -53
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for the formatting of empty method definitions.
|
7
|
+
# By default it enforces empty method definitions to go on a single
|
8
|
+
# line (compact style), but it cah be configured to enforce the `end`
|
9
|
+
# to go on its own line (expanded style.)
|
10
|
+
#
|
11
|
+
# Note: A method definition is not considered empty if it contains
|
12
|
+
# comments.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
#
|
16
|
+
# EnforcedStyle: compact (default)
|
17
|
+
#
|
18
|
+
# @bad
|
19
|
+
# def foo(bar)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @good
|
23
|
+
# def foo(bar); end
|
24
|
+
# def foo(bar)
|
25
|
+
# # baz
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# EnforcedStyle: expanded
|
29
|
+
#
|
30
|
+
# @bad
|
31
|
+
# def foo(bar); end
|
32
|
+
#
|
33
|
+
# @good
|
34
|
+
# def foo(bar)
|
35
|
+
# end
|
36
|
+
class EmptyMethod < Cop
|
37
|
+
include ConfigurableEnforcedStyle
|
38
|
+
|
39
|
+
MSG_COMPACT = 'Put empty method definitions on a single line.'.freeze
|
40
|
+
MSG_EXPANDED = 'Put the `end` of empty method definitions on the ' \
|
41
|
+
'next line.'.freeze
|
42
|
+
|
43
|
+
def on_def(node)
|
44
|
+
_method_name, _args, body = *node
|
45
|
+
|
46
|
+
return if body || comment_lines?(node)
|
47
|
+
return if compact_style? && compact?(node)
|
48
|
+
return if expanded_style? && expanded?(node)
|
49
|
+
|
50
|
+
add_offense(node, node.source_range, message)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def autocorrect(node)
|
56
|
+
lambda do |corrector|
|
57
|
+
corrector.replace(node.source_range, corrected(node))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def message
|
62
|
+
compact_style? ? MSG_COMPACT : MSG_EXPANDED
|
63
|
+
end
|
64
|
+
|
65
|
+
def corrected(node)
|
66
|
+
method_name, args, _body = *node
|
67
|
+
|
68
|
+
arguments = args.source unless args.children.empty?
|
69
|
+
joint = compact_style? ? '; ' : "\n"
|
70
|
+
|
71
|
+
["def #{method_name}#{arguments}", 'end'].join(joint)
|
72
|
+
end
|
73
|
+
|
74
|
+
def comment_lines?(node)
|
75
|
+
processed_source[line_range(node)].any? { |line| comment_line?(line) }
|
76
|
+
end
|
77
|
+
|
78
|
+
def compact?(node)
|
79
|
+
node.single_line?
|
80
|
+
end
|
81
|
+
|
82
|
+
def expanded?(node)
|
83
|
+
node.multiline?
|
84
|
+
end
|
85
|
+
|
86
|
+
def compact_style?
|
87
|
+
style == :compact
|
88
|
+
end
|
89
|
+
|
90
|
+
def expanded_style?
|
91
|
+
style == :expanded
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -16,71 +16,40 @@ module RuboCop
|
|
16
16
|
class EvenOdd < Cop
|
17
17
|
MSG = 'Replace with `Integer#%s?`.'.freeze
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
def_node_matcher :even_odd_candidate?, <<-PATTERN
|
20
|
+
(send
|
21
|
+
{(send $_ :% (int 2))
|
22
|
+
(begin (send $_ :% (int 2)))}
|
23
|
+
${:== :!=}
|
24
|
+
(int ${0 1 2}))
|
25
|
+
PATTERN
|
24
26
|
|
25
27
|
def on_send(node)
|
26
|
-
|
28
|
+
even_odd_candidate?(node) do |_base_number, method, arg|
|
29
|
+
replacement_method = replacement_method(arg, method)
|
27
30
|
add_offense(node, :expression, format(MSG, replacement_method))
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
34
|
def autocorrect(node)
|
32
|
-
|
33
|
-
|
35
|
+
even_odd_candidate?(node) do |base_number, method, arg|
|
36
|
+
replacement_method = replacement_method(arg, method)
|
37
|
+
|
38
|
+
correction = "#{base_number.source}.#{replacement_method}?"
|
34
39
|
->(corrector) { corrector.replace(node.source_range, correction) }
|
35
40
|
end
|
36
41
|
end
|
37
42
|
|
38
43
|
private
|
39
44
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
def offense_type(node)
|
47
|
-
receiver, method, args = *node
|
48
|
-
|
49
|
-
return unless equality_operator?(method)
|
50
|
-
return unless div_by_2?(receiver)
|
51
|
-
|
52
|
-
replacement_method(args, method) { |odd_or_even| yield odd_or_even }
|
53
|
-
end
|
54
|
-
|
55
|
-
def equality_operator?(method_name)
|
56
|
-
EQUALITY_OPERATORS.include?(method_name)
|
57
|
-
end
|
58
|
-
|
59
|
-
def div_by_2?(node)
|
60
|
-
node = expression(node)
|
61
|
-
|
62
|
-
_receiver, method, args = *node
|
63
|
-
|
64
|
-
method == :% && args == TWO
|
65
|
-
end
|
66
|
-
|
67
|
-
def replacement_method(args, method)
|
68
|
-
if args == ZERO
|
69
|
-
yield method == :== ? :even : :odd
|
70
|
-
elsif args == ONE
|
71
|
-
yield method == :== ? :odd : :even
|
45
|
+
def replacement_method(arg, method)
|
46
|
+
case arg
|
47
|
+
when 0
|
48
|
+
method == :== ? :even : :odd
|
49
|
+
when 1
|
50
|
+
method == :== ? :odd : :even
|
72
51
|
end
|
73
52
|
end
|
74
|
-
|
75
|
-
def expression(node)
|
76
|
-
return unless node
|
77
|
-
|
78
|
-
# check for scenarios like (x % 2) == 0
|
79
|
-
node = node.children.first if node.begin_type? && node.children.one?
|
80
|
-
|
81
|
-
return unless node.send_type?
|
82
|
-
node
|
83
|
-
end
|
84
53
|
end
|
85
54
|
end
|
86
55
|
end
|
@@ -69,7 +69,10 @@ module RuboCop
|
|
69
69
|
MSG_NO_MIXED_KEYS = "Don't mix styles in the same hash.".freeze
|
70
70
|
MSG_HASH_ROCKETS = 'Use hash rockets syntax.'.freeze
|
71
71
|
|
72
|
-
|
72
|
+
def initialize(*)
|
73
|
+
@force_hash_rockets = false
|
74
|
+
super
|
75
|
+
end
|
73
76
|
|
74
77
|
def on_hash(node)
|
75
78
|
if cop_config['UseHashRocketsWithSymbolValues']
|
@@ -70,32 +70,22 @@ module RuboCop
|
|
70
70
|
}
|
71
71
|
}.freeze
|
72
72
|
|
73
|
-
|
73
|
+
def_node_matcher :lambda_node?, '(block $(send nil :lambda) ...)'
|
74
74
|
|
75
75
|
def on_block(node)
|
76
|
-
|
77
|
-
|
78
|
-
# (send nil :lambda)
|
79
|
-
# ...)
|
80
|
-
block_method, _args, = *node
|
76
|
+
lambda_node?(node) do |block_method|
|
77
|
+
selector = block_method.source
|
81
78
|
|
82
|
-
|
79
|
+
return unless offending_selector?(node, selector)
|
83
80
|
|
84
|
-
|
81
|
+
add_offense(node,
|
82
|
+
block_method.source_range,
|
83
|
+
message(node, selector))
|
84
|
+
end
|
85
85
|
end
|
86
86
|
|
87
87
|
private
|
88
88
|
|
89
|
-
def check(node)
|
90
|
-
block_method, _args, = *node
|
91
|
-
|
92
|
-
selector = block_method.source
|
93
|
-
|
94
|
-
return unless offending_selector?(node, selector)
|
95
|
-
|
96
|
-
add_offense(node, block_method.source_range, message(node, selector))
|
97
|
-
end
|
98
|
-
|
99
89
|
def offending_selector?(node, selector)
|
100
90
|
lines = node.multiline? ? :multiline : :single_line
|
101
91
|
|
@@ -27,13 +27,13 @@ module RuboCop
|
|
27
27
|
class ModuleFunction < Cop
|
28
28
|
include ConfigurableEnforcedStyle
|
29
29
|
|
30
|
-
MODULE_FUNCTION_MSG =
|
31
|
-
|
32
|
-
EXTEND_SELF_MSG =
|
33
|
-
|
30
|
+
MODULE_FUNCTION_MSG =
|
31
|
+
'Use `module_function` instead of `extend self`.'.freeze
|
32
|
+
EXTEND_SELF_MSG =
|
33
|
+
'Use `extend self` instead of `module_function`.'.freeze
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
def_node_matcher :module_function_node?, '(send nil :module_function)'
|
36
|
+
def_node_matcher :extend_self_node?, '(send nil :extend self)'
|
37
37
|
|
38
38
|
def on_module(node)
|
39
39
|
_name, body = *node
|
@@ -47,11 +47,14 @@ module RuboCop
|
|
47
47
|
private
|
48
48
|
|
49
49
|
def each_wrong_style(nodes)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
case style
|
51
|
+
when :module_function
|
52
|
+
nodes.each do |node|
|
53
|
+
yield node, MODULE_FUNCTION_MSG if extend_self_node?(node)
|
54
|
+
end
|
55
|
+
when :extend_self
|
56
|
+
nodes.each do |node|
|
57
|
+
yield node, EXTEND_SELF_MSG if module_function_node?(node)
|
55
58
|
end
|
56
59
|
end
|
57
60
|
end
|
@@ -15,15 +15,12 @@ module RuboCop
|
|
15
15
|
class NilComparison < Cop
|
16
16
|
MSG = 'Prefer the use of the `nil?` predicate.'.freeze
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
NIL_NODE = s(:nil)
|
18
|
+
def_node_matcher :nil_comparison?, '(send _ {:== :===} (:nil))'
|
21
19
|
|
22
20
|
def on_send(node)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
add_offense(node, :selector) if args == NIL_NODE
|
21
|
+
nil_comparison?(node) do
|
22
|
+
add_offense(node, :selector)
|
23
|
+
end
|
27
24
|
end
|
28
25
|
|
29
26
|
private
|
@@ -27,36 +27,27 @@ module RuboCop
|
|
27
27
|
include OnMethodDef
|
28
28
|
include IfNode
|
29
29
|
|
30
|
-
|
30
|
+
def_node_matcher :not_equal_to_nil?, '(send _ :!= (:nil))'
|
31
|
+
def_node_matcher :unless_check?, '(if (send _ :nil?) ...)'
|
32
|
+
def_node_matcher :nil_check?, '(send _ :nil?)'
|
33
|
+
def_node_matcher :not_and_nil_check?, '(send (send _ :nil?) :!)'
|
31
34
|
|
32
35
|
def on_send(node)
|
33
36
|
return if ignored_node?(node)
|
34
|
-
receiver, method, args = *node
|
35
37
|
|
36
|
-
if not_equal_to_nil?(
|
38
|
+
if not_equal_to_nil?(node)
|
37
39
|
add_offense(node, :selector)
|
38
40
|
elsif include_semantic_changes? &&
|
39
|
-
(not_and_nil_check?(
|
40
|
-
unless_and_nil_check?(node, method))
|
41
|
+
(not_and_nil_check?(node) || unless_and_nil_check?(node))
|
41
42
|
add_offense(node, :expression)
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
46
|
private
|
46
47
|
|
47
|
-
def
|
48
|
-
method == :!= && args == NIL_NODE
|
49
|
-
end
|
50
|
-
|
51
|
-
def not_and_nil_check?(method, receiver)
|
52
|
-
method == :! && nil_check?(receiver)
|
53
|
-
end
|
54
|
-
|
55
|
-
def unless_and_nil_check?(send_node, method)
|
56
|
-
return unless method == :nil?
|
57
|
-
|
48
|
+
def unless_and_nil_check?(send_node)
|
58
49
|
parent = send_node.parent
|
59
|
-
|
50
|
+
nil_check?(send_node) && unless_check?(parent) && !ternary?(parent) &&
|
60
51
|
parent.loc.keyword.is?('unless')
|
61
52
|
end
|
62
53
|
|
@@ -84,21 +75,15 @@ module RuboCop
|
|
84
75
|
end
|
85
76
|
end
|
86
77
|
|
87
|
-
def nil_check?(node)
|
88
|
-
return false unless node && node.send_type?
|
89
|
-
|
90
|
-
_receiver, method, *_args = *node
|
91
|
-
method == :nil?
|
92
|
-
end
|
93
|
-
|
94
78
|
def autocorrect(node)
|
95
79
|
receiver, method, _args = *node
|
96
80
|
|
97
|
-
|
81
|
+
case method
|
82
|
+
when :!=
|
98
83
|
autocorrect_comparison(node)
|
99
|
-
|
84
|
+
when :!
|
100
85
|
autocorrect_non_nil(node, receiver)
|
101
|
-
|
86
|
+
when :nil?
|
102
87
|
autocorrect_unless_nil(node, receiver)
|
103
88
|
end
|
104
89
|
end
|
@@ -106,18 +91,15 @@ module RuboCop
|
|
106
91
|
def autocorrect_comparison(node)
|
107
92
|
expr = node.source
|
108
93
|
|
109
|
-
new_code =
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
end
|
94
|
+
new_code = if include_semantic_changes?
|
95
|
+
expr.sub(/\s*!=\s*nil/, '')
|
96
|
+
else
|
97
|
+
expr.sub(/^(\S*)\s*!=\s*nil/, '!\1.nil?')
|
98
|
+
end
|
115
99
|
|
116
100
|
return if expr == new_code
|
117
101
|
|
118
|
-
|
119
|
-
corrector.replace(node.source_range, new_code)
|
120
|
-
end
|
102
|
+
->(corrector) { corrector.replace(node.source_range, new_code) }
|
121
103
|
end
|
122
104
|
|
123
105
|
def autocorrect_non_nil(node, inner_node)
|
@@ -3,11 +3,15 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop checks for usage of comparison operators (`==`,
|
7
|
-
# `>`, `<`) to test numbers as zero,
|
6
|
+
# This cop checks for usage of comparison operators (`==`,
|
7
|
+
# `>`, `<`) to test numbers as zero, positive, or negative.
|
8
8
|
# These can be replaced by their respective predicate methods.
|
9
9
|
# The cop can also be configured to do the reverse.
|
10
10
|
#
|
11
|
+
# The cop disregards `nonzero?` as it its value is truthy or falsey,
|
12
|
+
# but not `true` and `false`, and thus not always interchangeable with
|
13
|
+
# `!= 0`.
|
14
|
+
#
|
11
15
|
# @example
|
12
16
|
#
|
13
17
|
# # EnforcedStyle: predicate (default)
|
@@ -15,14 +19,12 @@ module RuboCop
|
|
15
19
|
# # bad
|
16
20
|
#
|
17
21
|
# foo == 0
|
18
|
-
# 0 != bar.baz
|
19
22
|
# 0 > foo
|
20
23
|
# bar.baz > 0
|
21
24
|
#
|
22
25
|
# # good
|
23
26
|
#
|
24
27
|
# foo.zero?
|
25
|
-
# bar.baz.nonzero?
|
26
28
|
# foo.negative?
|
27
29
|
# bar.baz.positive?
|
28
30
|
#
|
@@ -33,14 +35,12 @@ module RuboCop
|
|
33
35
|
# # bad
|
34
36
|
#
|
35
37
|
# foo.zero?
|
36
|
-
# bar.baz.nonzero?
|
37
38
|
# foo.negative?
|
38
39
|
# bar.baz.positive?
|
39
40
|
#
|
40
41
|
# # good
|
41
42
|
#
|
42
43
|
# foo == 0
|
43
|
-
# 0 != bar.baz
|
44
44
|
# 0 > foo
|
45
45
|
# bar.baz > 0
|
46
46
|
class NumericPredicate < Cop
|
@@ -50,7 +50,6 @@ module RuboCop
|
|
50
50
|
|
51
51
|
REPLACEMENTS = {
|
52
52
|
'zero?' => '==',
|
53
|
-
'nonzero?' => '!=',
|
54
53
|
'positive?' => '>',
|
55
54
|
'negative?' => '<'
|
56
55
|
}.freeze
|
@@ -125,15 +124,15 @@ module RuboCop
|
|
125
124
|
end
|
126
125
|
|
127
126
|
def_node_matcher :predicate, <<-PATTERN
|
128
|
-
(send $(...) ${:zero? :
|
127
|
+
(send $(...) ${:zero? :positive? :negative?})
|
129
128
|
PATTERN
|
130
129
|
|
131
130
|
def_node_matcher :comparison, <<-PATTERN
|
132
|
-
(send $(...) ${:==
|
131
|
+
(send $(...) ${:== :> :<} (int 0))
|
133
132
|
PATTERN
|
134
133
|
|
135
134
|
def_node_matcher :inverted_comparison, <<-PATTERN
|
136
|
-
(send (int 0) ${:==
|
135
|
+
(send (int 0) ${:== :> :<} $(...))
|
137
136
|
PATTERN
|
138
137
|
end
|
139
138
|
end
|