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.

Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +17 -0
  4. data/config/enabled.yml +29 -2
  5. data/lib/rubocop.rb +6 -1
  6. data/lib/rubocop/config.rb +0 -10
  7. data/lib/rubocop/config_loader.rb +21 -9
  8. data/lib/rubocop/cop/bundler/duplicated_gem.rb +69 -0
  9. data/lib/rubocop/cop/bundler/ordered_gems.rb +54 -0
  10. data/lib/rubocop/cop/cop.rb +1 -0
  11. data/lib/rubocop/cop/lint/debugger.rb +9 -1
  12. data/lib/rubocop/cop/lint/each_with_object_argument.rb +5 -6
  13. data/lib/rubocop/cop/lint/eval.rb +3 -7
  14. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +6 -4
  15. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +13 -4
  16. data/lib/rubocop/cop/lint/useless_comparison.rb +5 -9
  17. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
  18. data/lib/rubocop/cop/metrics/line_length.rb +16 -3
  19. data/lib/rubocop/cop/mixin/access_modifier_node.rb +9 -9
  20. data/lib/rubocop/cop/mixin/configurable_numbering.rb +14 -7
  21. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +92 -20
  22. data/lib/rubocop/cop/performance/compare_with_block.rb +61 -0
  23. data/lib/rubocop/cop/performance/count.rb +21 -57
  24. data/lib/rubocop/cop/performance/detect.rb +15 -15
  25. data/lib/rubocop/cop/performance/flat_map.rb +23 -35
  26. data/lib/rubocop/cop/performance/sample.rb +84 -82
  27. data/lib/rubocop/cop/performance/string_replacement.rb +18 -43
  28. data/lib/rubocop/cop/rails/enum_uniqueness.rb +71 -0
  29. data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
  30. data/lib/rubocop/cop/rails/output.rb +8 -12
  31. data/lib/rubocop/cop/rails/read_write_attribute.rb +10 -6
  32. data/lib/rubocop/cop/rails/request_referer.rb +8 -9
  33. data/lib/rubocop/cop/rails/scope_args.rb +5 -11
  34. data/lib/rubocop/cop/style/access_modifier_indentation.rb +1 -1
  35. data/lib/rubocop/cop/style/and_or.rb +1 -1
  36. data/lib/rubocop/cop/style/array_join.rb +4 -8
  37. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  38. data/lib/rubocop/cop/style/case_equality.rb +3 -3
  39. data/lib/rubocop/cop/style/character_literal.rb +2 -4
  40. data/lib/rubocop/cop/style/class_check.rb +6 -6
  41. data/lib/rubocop/cop/style/colon_method_call.rb +6 -6
  42. data/lib/rubocop/cop/style/each_with_object.rb +13 -17
  43. data/lib/rubocop/cop/style/empty_literal.rb +46 -36
  44. data/lib/rubocop/cop/style/empty_method.rb +96 -0
  45. data/lib/rubocop/cop/style/even_odd.rb +19 -50
  46. data/lib/rubocop/cop/style/hash_syntax.rb +4 -1
  47. data/lib/rubocop/cop/style/lambda.rb +8 -18
  48. data/lib/rubocop/cop/style/module_function.rb +14 -11
  49. data/lib/rubocop/cop/style/nil_comparison.rb +4 -7
  50. data/lib/rubocop/cop/style/non_nil_check.rb +18 -36
  51. data/lib/rubocop/cop/style/numeric_predicate.rb +9 -10
  52. data/lib/rubocop/cop/style/op_method.rb +7 -9
  53. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
  54. data/lib/rubocop/cop/style/proc.rb +5 -9
  55. data/lib/rubocop/cop/style/redundant_freeze.rb +6 -7
  56. data/lib/rubocop/cop/style/send.rb +6 -3
  57. data/lib/rubocop/cop/style/space_inside_block_braces.rb +1 -1
  58. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  59. data/lib/rubocop/cop/style/symbol_proc.rb +22 -43
  60. data/lib/rubocop/cop/style/ternary_parentheses.rb +67 -18
  61. data/lib/rubocop/cop/util.rb +1 -1
  62. data/lib/rubocop/cop/variable_force/assignment.rb +2 -0
  63. data/lib/rubocop/cop/variable_force/locatable.rb +8 -6
  64. data/lib/rubocop/cop/variable_force/reference.rb +2 -0
  65. data/lib/rubocop/formatter/base_formatter.rb +4 -8
  66. data/lib/rubocop/formatter/fuubar_style_formatter.rb +6 -0
  67. data/lib/rubocop/node_pattern.rb +7 -5
  68. data/lib/rubocop/processed_source.rb +1 -0
  69. data/lib/rubocop/rspec/cop_helper.rb +4 -0
  70. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +1 -1
  71. data/lib/rubocop/version.rb +1 -1
  72. metadata +7 -3
  73. 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
- ZERO = s(:int, 0)
20
- ONE = s(:int, 1)
21
- TWO = s(:int, 2)
22
-
23
- EQUALITY_OPERATORS = [:==, :!=].freeze
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
- offense_type(node) do |replacement_method|
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
- offense_type(node) do |replacement_method|
33
- correction = "#{base_number(node)}.#{replacement_method}?"
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 base_number(node)
41
- receiver, = *node
42
- node = expression(receiver)
43
- node.children.first.source
44
- end
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
- @force_hash_rockets = false
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
- TARGET = s(:send, nil, :lambda)
73
+ def_node_matcher :lambda_node?, '(block $(send nil :lambda) ...)'
74
74
 
75
75
  def on_block(node)
76
- # We're looking for
77
- # (block
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
- return unless block_method == TARGET
79
+ return unless offending_selector?(node, selector)
83
80
 
84
- check(node)
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 = 'Use `module_function` instead of `extend self`.'
31
- .freeze
32
- EXTEND_SELF_MSG = 'Use `extend self` instead of `module_function`.'
33
- .freeze
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
- MODULE_FUNCTION_NODE = s(:send, nil, :module_function)
36
- EXTEND_SELF_NODE = s(:send, nil, :extend, s(:self))
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
- nodes.each do |node|
51
- if style == :module_function && node == EXTEND_SELF_NODE
52
- yield node, MODULE_FUNCTION_MSG
53
- elsif style == :extend_self && node == MODULE_FUNCTION_NODE
54
- yield node, EXTEND_SELF_MSG
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
- OPS = [:==, :===].freeze
19
-
20
- NIL_NODE = s(:nil)
18
+ def_node_matcher :nil_comparison?, '(send _ {:== :===} (:nil))'
21
19
 
22
20
  def on_send(node)
23
- _receiver, method, args = *node
24
- return unless OPS.include?(method)
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
- NIL_NODE = s(:nil)
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?(method, args)
38
+ if not_equal_to_nil?(node)
37
39
  add_offense(node, :selector)
38
40
  elsif include_semantic_changes? &&
39
- (not_and_nil_check?(method, receiver) ||
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 not_equal_to_nil?(method, args)
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
- parent && parent.if_type? && !ternary?(parent) &&
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
- if method == :!=
81
+ case method
82
+ when :!=
98
83
  autocorrect_comparison(node)
99
- elsif method == :!
84
+ when :!
100
85
  autocorrect_non_nil(node, receiver)
101
- elsif method == :nil?
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
- if include_semantic_changes?
111
- expr.sub(/\s*!=\s*nil/, '')
112
- else
113
- expr.sub(/^(\S*)\s*!=\s*nil/, '!\1.nil?')
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
- lambda do |corrector|
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, nonzero, positive, or negative.
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? :nonzero? :positive? :negative?})
127
+ (send $(...) ${:zero? :positive? :negative?})
129
128
  PATTERN
130
129
 
131
130
  def_node_matcher :comparison, <<-PATTERN
132
- (send $(...) ${:== :!= :> :<} (int 0))
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