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
@@ -18,19 +18,17 @@ module RuboCop
|
|
18
18
|
'name its argument `other`.'.freeze
|
19
19
|
|
20
20
|
OP_LIKE_METHODS = [:eql?, :equal?].freeze
|
21
|
-
|
22
21
|
BLACKLISTED = [:+@, :-@, :[], :[]=, :<<, :`].freeze
|
23
22
|
|
24
|
-
|
25
|
-
|
23
|
+
def_node_matcher :op_method_candidate?, <<-PATTERN
|
24
|
+
(def $_ (args $(arg [!:other !:_other])) _)
|
25
|
+
PATTERN
|
26
26
|
|
27
27
|
def on_def(node)
|
28
|
-
name,
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
add_offense(args.children.first, :expression, format(MSG, name))
|
28
|
+
op_method_candidate?(node) do |name, arg|
|
29
|
+
return unless op_method?(name)
|
30
|
+
add_offense(arg, :expression, format(MSG, name))
|
31
|
+
end
|
34
32
|
end
|
35
33
|
|
36
34
|
def op_method?(name)
|
@@ -8,17 +8,13 @@ module RuboCop
|
|
8
8
|
class Proc < Cop
|
9
9
|
MSG = 'Use `proc` instead of `Proc.new`.'.freeze
|
10
10
|
|
11
|
-
|
11
|
+
def_node_matcher :proc_new?,
|
12
|
+
'(block $(send (const nil :Proc) :new) ...)'
|
12
13
|
|
13
14
|
def on_block(node)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# (const nil :Proc) :new)
|
18
|
-
# ...)
|
19
|
-
block_method, = *node
|
20
|
-
|
21
|
-
add_offense(block_method, :expression) if block_method == TARGET
|
15
|
+
proc_new?(node) do |block_method|
|
16
|
+
add_offense(block_method, :expression)
|
17
|
+
end
|
22
18
|
end
|
23
19
|
|
24
20
|
def autocorrect(node)
|
@@ -16,14 +16,13 @@ module RuboCop
|
|
16
16
|
|
17
17
|
MSG = 'Freezing immutable objects is pointless.'.freeze
|
18
18
|
|
19
|
-
|
20
|
-
receiver, method_name, *args = *node
|
21
|
-
|
22
|
-
return unless method_name == :freeze &&
|
23
|
-
args.empty? &&
|
24
|
-
immutable_literal?(receiver)
|
19
|
+
def_node_matcher :freezing?, '(send $_ :freeze)'
|
25
20
|
|
26
|
-
|
21
|
+
def on_send(node)
|
22
|
+
freezing?(node) do |receiver|
|
23
|
+
return unless immutable_literal?(receiver)
|
24
|
+
add_offense(node, :expression)
|
25
|
+
end
|
27
26
|
end
|
28
27
|
|
29
28
|
def autocorrect(node)
|
@@ -8,10 +8,13 @@ module RuboCop
|
|
8
8
|
MSG = 'Prefer `Object#__send__` or `Object#public_send` to ' \
|
9
9
|
'`send`.'.freeze
|
10
10
|
|
11
|
+
def_node_matcher :sending?, '(send _ :send $...)'
|
12
|
+
|
11
13
|
def on_send(node)
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
sending?(node) do |args|
|
15
|
+
return if args.empty?
|
16
|
+
add_offense(node, :selector)
|
17
|
+
end
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
@@ -7,10 +7,10 @@ module RuboCop
|
|
7
7
|
class SpecialGlobalVars < Cop
|
8
8
|
include ConfigurableEnforcedStyle
|
9
9
|
|
10
|
-
MSG_BOTH = 'Prefer `%s` from the stdlib \'English\' module
|
11
|
-
'or `%s` over `%s`.'.freeze
|
10
|
+
MSG_BOTH = 'Prefer `%s` from the stdlib \'English\' module ' \
|
11
|
+
'(don\'t forget to require it), or `%s` over `%s`.'.freeze
|
12
12
|
MSG_ENGLISH = 'Prefer `%s` from the stdlib \'English\' module ' \
|
13
|
-
'over `%s`.'.freeze
|
13
|
+
'(don\'t forget to require it) over `%s`.'.freeze
|
14
14
|
MSG_REGULAR = 'Prefer `%s` over `%s`.'.freeze
|
15
15
|
|
16
16
|
ENGLISH_VARS = { # rubocop:disable Style/MutableConstant
|
@@ -13,23 +13,30 @@ module RuboCop
|
|
13
13
|
# something.map(&:upcase)
|
14
14
|
class SymbolProc < Cop
|
15
15
|
MSG = 'Pass `&:%s` as an argument to `%s` instead of a block.'.freeze
|
16
|
+
SUPER_TYPES = [:super, :zsuper].freeze
|
16
17
|
|
17
|
-
|
18
|
+
def_node_matcher :proc_node?, '(send (const nil :Proc) :new)'
|
19
|
+
def_node_matcher :symbol_proc?, <<-PATTERN
|
20
|
+
(block
|
21
|
+
${(send ...) (super ...) zsuper}
|
22
|
+
$(args (arg _))
|
23
|
+
$(send lvar $_))
|
24
|
+
PATTERN
|
18
25
|
|
19
26
|
def on_block(node)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
symbol_proc?(node) do |send_or_super, block_args, block_body, method|
|
28
|
+
block_method_name = resolve_block_method_name(send_or_super)
|
29
|
+
|
30
|
+
# TODO: Rails-specific handling that we should probably make
|
31
|
+
# configurable - https://github.com/bbatsov/rubocop/issues/1485
|
32
|
+
# we should ignore lambdas & procs
|
33
|
+
return if proc_node?(send_or_super)
|
34
|
+
return if [:lambda, :proc].include?(block_method_name)
|
35
|
+
return if ignored_method?(block_method_name)
|
36
|
+
return unless can_shorten?(block_args, block_body)
|
37
|
+
|
38
|
+
offense(node, method, block_method_name)
|
39
|
+
end
|
33
40
|
end
|
34
41
|
|
35
42
|
def autocorrect(node)
|
@@ -114,9 +121,6 @@ module RuboCop
|
|
114
121
|
end
|
115
122
|
|
116
123
|
def can_shorten?(block_args, block_body)
|
117
|
-
return false unless shortenable_args?(block_args) &&
|
118
|
-
shortenable_body?(block_body)
|
119
|
-
|
120
124
|
argument_matches_receiver?(block_args, block_body)
|
121
125
|
end
|
122
126
|
|
@@ -130,33 +134,8 @@ module RuboCop
|
|
130
134
|
block_arg_name == receiver_name
|
131
135
|
end
|
132
136
|
|
133
|
-
# The block body must have a single send without arguments to an
|
134
|
-
# lvar type.
|
135
|
-
# E.g.: `foo { |bar| bar.baz }`
|
136
|
-
def shortenable_body?(block_body)
|
137
|
-
return false unless block_body && block_body.send_type?
|
138
|
-
|
139
|
-
receiver, _, args = *block_body
|
140
|
-
|
141
|
-
return false if args
|
142
|
-
|
143
|
-
receiver && receiver.lvar_type?
|
144
|
-
end
|
145
|
-
|
146
|
-
# The block must have a single, shortenable argument.
|
147
|
-
# E.g.: `foo { |bar| ... }`
|
148
|
-
def shortenable_args?(block_args)
|
149
|
-
block_args.children.one? && !non_shortenable_args?(block_args)
|
150
|
-
end
|
151
|
-
|
152
137
|
def super?(node)
|
153
|
-
|
154
|
-
end
|
155
|
-
|
156
|
-
def non_shortenable_args?(block_args)
|
157
|
-
# something { |&x| ... }
|
158
|
-
# something { |*x| ... }
|
159
|
-
[:blockarg, :restarg].include?(block_args.children.first.type)
|
138
|
+
SUPER_TYPES.include?(node.type)
|
160
139
|
end
|
161
140
|
end
|
162
141
|
end
|
@@ -34,17 +34,32 @@ module RuboCop
|
|
34
34
|
# foo = (bar?) ? a : b
|
35
35
|
# foo = (bar.baz) ? a : b
|
36
36
|
# foo = (bar && baz) ? a : b
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
#
|
40
|
+
# EnforcedStyle: require_parentheses_when_complex
|
41
|
+
#
|
42
|
+
# @bad
|
43
|
+
# foo = (bar?) ? a : b
|
44
|
+
# foo = (bar.baz?) ? a : b
|
45
|
+
# foo = bar && baz ? a : b
|
46
|
+
#
|
47
|
+
# @good
|
48
|
+
# foo = bar? ? a : b
|
49
|
+
# foo = bar.baz ? a : b
|
50
|
+
# foo = (bar && baz) ? a : b
|
37
51
|
class TernaryParentheses < Cop
|
38
52
|
include IfNode
|
39
53
|
include SafeAssignment
|
40
54
|
include ConfigurableEnforcedStyle
|
41
55
|
|
42
56
|
MSG = '%s parentheses for ternary conditions.'.freeze
|
57
|
+
MSG_COMPLEX = '%s parentheses for ternary expressions with' \
|
58
|
+
' complex conditions.'.freeze
|
43
59
|
|
44
60
|
def on_if(node)
|
45
|
-
return unless ternary?(node)
|
46
|
-
|
47
|
-
add_offense(node, node.source_range, message) if offense?(node)
|
61
|
+
return unless ternary?(node) && !infinite_loop? && offense?(node)
|
62
|
+
add_offense(node, node.source_range, message(node))
|
48
63
|
end
|
49
64
|
|
50
65
|
private
|
@@ -52,39 +67,74 @@ module RuboCop
|
|
52
67
|
def offense?(node)
|
53
68
|
condition, = *node
|
54
69
|
|
55
|
-
|
56
|
-
!
|
57
|
-
|
58
|
-
|
70
|
+
if safe_assignment?(condition)
|
71
|
+
!safe_assignment_allowed?
|
72
|
+
else
|
73
|
+
parens = parenthesized?(condition)
|
74
|
+
case style
|
75
|
+
when :require_parentheses_when_complex
|
76
|
+
complex_condition?(condition) ? !parens : parens
|
77
|
+
else
|
78
|
+
require_parentheses? ? !parens : parens
|
79
|
+
end
|
80
|
+
end
|
59
81
|
end
|
60
82
|
|
61
83
|
def autocorrect(node)
|
62
84
|
condition, = *node
|
63
85
|
|
86
|
+
return nil if parenthesized?(condition) &&
|
87
|
+
(safe_assignment?(condition) ||
|
88
|
+
unsafe_autocorrect?(condition))
|
89
|
+
|
64
90
|
lambda do |corrector|
|
65
|
-
if
|
91
|
+
if parenthesized?(condition)
|
92
|
+
corrector.remove(condition.loc.begin)
|
93
|
+
corrector.remove(condition.loc.end)
|
94
|
+
else
|
66
95
|
corrector.insert_before(condition.source_range, '(')
|
67
96
|
corrector.insert_after(condition.source_range, ')')
|
68
|
-
else
|
69
|
-
unless safe_assignment?(condition) ||
|
70
|
-
unsafe_autocorrect?(condition)
|
71
|
-
corrector.remove(condition.loc.begin)
|
72
|
-
corrector.remove(condition.loc.end)
|
73
|
-
end
|
74
97
|
end
|
75
98
|
end
|
76
99
|
end
|
77
100
|
|
78
|
-
|
79
|
-
|
101
|
+
# If the condition is parenthesized we recurse and check for any
|
102
|
+
# complex expressions within it.
|
103
|
+
def complex_condition?(condition)
|
104
|
+
if condition.type == :begin
|
105
|
+
condition.to_a.any? { |x| complex_condition?(x) }
|
106
|
+
else
|
107
|
+
non_complex_type?(condition) ? false : true
|
108
|
+
end
|
109
|
+
end
|
80
110
|
|
81
|
-
|
111
|
+
# Anything that is not a variable, constant, or method/.method call
|
112
|
+
# will be counted as a complex expression.
|
113
|
+
def non_complex_type?(condition)
|
114
|
+
condition.variable? || condition.const_type? ||
|
115
|
+
(condition.send_type? && !operator?(condition.method_name)) ||
|
116
|
+
condition.defined_type?
|
117
|
+
end
|
118
|
+
|
119
|
+
def message(node)
|
120
|
+
if require_parentheses_when_complex?
|
121
|
+
condition, = *node
|
122
|
+
omit = parenthesized?(condition) ? 'Only use' : 'Use'
|
123
|
+
format(MSG_COMPLEX, omit)
|
124
|
+
else
|
125
|
+
verb = require_parentheses? ? 'Use' : 'Omit'
|
126
|
+
format(MSG, verb)
|
127
|
+
end
|
82
128
|
end
|
83
129
|
|
84
130
|
def require_parentheses?
|
85
131
|
style == :require_parentheses
|
86
132
|
end
|
87
133
|
|
134
|
+
def require_parentheses_when_complex?
|
135
|
+
style == :require_parentheses_when_complex
|
136
|
+
end
|
137
|
+
|
88
138
|
def redundant_parentheses_enabled?
|
89
139
|
@config.for_cop('RedundantParentheses')['Enabled']
|
90
140
|
end
|
@@ -109,7 +159,6 @@ module RuboCop
|
|
109
159
|
|
110
160
|
def unparenthesized_method_call?(child)
|
111
161
|
argument = method_call_argument(child)
|
112
|
-
|
113
162
|
argument && argument !~ /^\(/
|
114
163
|
end
|
115
164
|
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -24,7 +24,7 @@ module RuboCop
|
|
24
24
|
|
25
25
|
# Match literal regex characters, not including anchors, character
|
26
26
|
# classes, alternatives, groups, repetitions, references, etc
|
27
|
-
LITERAL_REGEX = /[\w\s\-,"'!#%&<>=;:`~]|\\[^
|
27
|
+
LITERAL_REGEX = /[\w\s\-,"'!#%&<>=;:`~]|\\[^AbBdDgGhHkpPRwWXsSzZ0-9]/
|
28
28
|
|
29
29
|
module_function
|
30
30
|
|
@@ -21,6 +21,12 @@ module RuboCop
|
|
21
21
|
NON_FOR_LOOP_TYPES = LOOP_TYPES - [FOR_LOOP_TYPE]
|
22
22
|
NON_FOR_LOOP_TYPES_CHILD_INDEX = 1
|
23
23
|
|
24
|
+
def initialize(*)
|
25
|
+
@branch_point_node = @branch_body_node = nil
|
26
|
+
|
27
|
+
super()
|
28
|
+
end
|
29
|
+
|
24
30
|
def node
|
25
31
|
raise '#node must be declared!'
|
26
32
|
end
|
@@ -64,9 +70,7 @@ module RuboCop
|
|
64
70
|
|
65
71
|
# Inner if, case, rescue, or ensure node.
|
66
72
|
def branch_point_node
|
67
|
-
if
|
68
|
-
return @branch_point_node
|
69
|
-
end
|
73
|
+
return @branch_point_node if @branch_point_node
|
70
74
|
|
71
75
|
set_branch_point_and_body_nodes!
|
72
76
|
@branch_point_node
|
@@ -74,9 +78,7 @@ module RuboCop
|
|
74
78
|
|
75
79
|
# A child node of #branch_point_node this assignment belongs.
|
76
80
|
def branch_body_node
|
77
|
-
if
|
78
|
-
return @branch_body_node
|
79
|
-
end
|
81
|
+
return @branch_body_node if @branch_body_node
|
80
82
|
|
81
83
|
set_branch_point_and_body_nodes!
|
82
84
|
@branch_body_node
|
@@ -77,8 +77,7 @@ module RuboCop
|
|
77
77
|
# all target file paths to be inspected
|
78
78
|
#
|
79
79
|
# @return [void]
|
80
|
-
def started(target_files)
|
81
|
-
end
|
80
|
+
def started(target_files); end
|
82
81
|
|
83
82
|
# @api public
|
84
83
|
#
|
@@ -91,8 +90,7 @@ module RuboCop
|
|
91
90
|
# file specific information, currently this is always empty.
|
92
91
|
#
|
93
92
|
# @return [void]
|
94
|
-
def file_started(file, options)
|
95
|
-
end
|
93
|
+
def file_started(file, options); end
|
96
94
|
|
97
95
|
# @api public
|
98
96
|
#
|
@@ -107,8 +105,7 @@ module RuboCop
|
|
107
105
|
# @return [void]
|
108
106
|
#
|
109
107
|
# @see RuboCop::Cop::Offense
|
110
|
-
def file_finished(file, offenses)
|
111
|
-
end
|
108
|
+
def file_finished(file, offenses); end
|
112
109
|
|
113
110
|
# @api public
|
114
111
|
#
|
@@ -120,8 +117,7 @@ module RuboCop
|
|
120
117
|
# unless RuboCop is interrupted by user.
|
121
118
|
#
|
122
119
|
# @return [void]
|
123
|
-
def finished(inspected_files)
|
124
|
-
end
|
120
|
+
def finished(inspected_files); end
|
125
121
|
end
|
126
122
|
end
|
127
123
|
end
|