rubocop 0.55.0 → 0.56.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +45 -0
  4. data/config/disabled.yml +4 -4
  5. data/config/enabled.yml +32 -16
  6. data/lib/rubocop.rb +8 -2
  7. data/lib/rubocop/cli.rb +4 -0
  8. data/lib/rubocop/comment_config.rb +36 -9
  9. data/lib/rubocop/config.rb +8 -1
  10. data/lib/rubocop/cop/generator.rb +4 -3
  11. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +101 -29
  12. data/lib/rubocop/cop/{style → layout}/empty_line_after_guard_clause.rb +1 -1
  13. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +5 -5
  14. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +112 -2
  15. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +8 -4
  16. data/lib/rubocop/cop/lint/erb_new_arguments.rb +107 -0
  17. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
  18. data/lib/rubocop/cop/lint/nested_percent_literal.rb +0 -8
  19. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  20. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  21. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -0
  22. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +16 -3
  23. data/lib/rubocop/cop/lint/splat_keyword_arguments.rb +36 -0
  24. data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +20 -2
  25. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +95 -0
  26. data/lib/rubocop/cop/performance/unneeded_sort.rb +41 -6
  27. data/lib/rubocop/cop/rails/assert_not.rb +44 -0
  28. data/lib/rubocop/cop/rails/blank.rb +34 -28
  29. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -1
  30. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +12 -2
  31. data/lib/rubocop/cop/rails/http_positional_arguments.rb +7 -7
  32. data/lib/rubocop/cop/rails/present.rb +31 -25
  33. data/lib/rubocop/cop/rails/refute_methods.rb +76 -0
  34. data/lib/rubocop/cop/rails/reversible_migration.rb +6 -4
  35. data/lib/rubocop/cop/rails/save_bang.rb +4 -1
  36. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -10
  37. data/lib/rubocop/cop/style/command_literal.rb +15 -3
  38. data/lib/rubocop/cop/style/comment_annotation.rb +6 -1
  39. data/lib/rubocop/cop/style/empty_method.rb +6 -3
  40. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +12 -2
  41. data/lib/rubocop/cop/style/method_missing_super.rb +34 -0
  42. data/lib/rubocop/cop/style/{method_missing.rb → missing_respond_to_missing.rb} +7 -29
  43. data/lib/rubocop/cop/style/parentheses_around_condition.rb +28 -2
  44. data/lib/rubocop/node_pattern.rb +1 -1
  45. data/lib/rubocop/processed_source.rb +12 -6
  46. data/lib/rubocop/result_cache.rb +9 -4
  47. data/lib/rubocop/rspec/shared_contexts.rb +4 -0
  48. data/lib/rubocop/runner.rb +8 -2
  49. data/lib/rubocop/target_finder.rb +40 -60
  50. data/lib/rubocop/version.rb +1 -1
  51. metadata +10 -4
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- module Style
5
+ module Layout
6
6
  # This cop enforces empty line after guard clause
7
7
  #
8
8
  # @example
@@ -6,12 +6,12 @@ module RuboCop
6
6
  # This cop checks whether method definitions are
7
7
  # separated by one empty line.
8
8
  #
9
- # `NumberOfEmptyLines` can be and integer (e.g. 1 by default) or
10
- # an array (e.g. [1, 2]) to specificy a minimum and a maximum of
11
- # empty lines.
9
+ # `NumberOfEmptyLines` can be an integer (default is 1) or
10
+ # an array (e.g. [1, 2]) to specify a minimum and maximum
11
+ # number of empty lines permitted.
12
12
  #
13
- # `AllowAdjacentOneLineDefs` can be used to configure is adjacent
14
- # one line methods definitions are an offense
13
+ # `AllowAdjacentOneLineDefs` configures whether adjacent
14
+ # one-line method definitions are considered an offense.
15
15
  #
16
16
  # @example
17
17
  #
@@ -4,8 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Layout
6
6
  # This cop checks the indentation of the first parameter in a method call.
7
- # Parameters after the first one are checked by Style/AlignParameters, not
8
- # by this cop.
7
+ # Parameters after the first one are checked by Layout/AlignParameters,
8
+ # not by this cop.
9
9
  #
10
10
  # @example
11
11
  #
@@ -14,10 +14,119 @@ module RuboCop
14
14
  # first_param,
15
15
  # second_param)
16
16
  #
17
+ # foo = some_method(
18
+ # first_param,
19
+ # second_param)
20
+ #
21
+ # foo = some_method(nested_call(
22
+ # nested_first_param),
23
+ # second_param)
24
+ #
25
+ # foo = some_method(
26
+ # nested_call(
27
+ # nested_first_param),
28
+ # second_param)
29
+ #
30
+ # some_method nested_call(
31
+ # nested_first_param),
32
+ # second_param
33
+ #
34
+ # # Style: consistent
35
+ #
36
+ # # good
37
+ # some_method(
38
+ # first_param,
39
+ # second_param)
40
+ #
41
+ # foo = some_method(
42
+ # first_param,
43
+ # second_param)
44
+ #
45
+ # foo = some_method(nested_call(
46
+ # nested_first_param),
47
+ # second_param)
48
+ #
49
+ # foo = some_method(
50
+ # nested_call(
51
+ # nested_first_param),
52
+ # second_param)
53
+ #
54
+ # some_method nested_call(
55
+ # nested_first_param),
56
+ # second_param
57
+ #
58
+ # # Style: consistent_relative_to_receiver
59
+ #
17
60
  # # good
18
61
  # some_method(
19
62
  # first_param,
20
63
  # second_param)
64
+ #
65
+ # foo = some_method(
66
+ # first_param,
67
+ # second_param)
68
+ #
69
+ # foo = some_method(nested_call(
70
+ # nested_first_param),
71
+ # second_param)
72
+ #
73
+ # foo = some_method(
74
+ # nested_call(
75
+ # nested_first_param),
76
+ # second_param)
77
+ #
78
+ # some_method nested_call(
79
+ # nested_first_param),
80
+ # second_params
81
+ #
82
+ # # Style: special_for_inner_method_call
83
+ #
84
+ # # good
85
+ # some_method(
86
+ # first_param,
87
+ # second_param)
88
+ #
89
+ # foo = some_method(
90
+ # first_param,
91
+ # second_param)
92
+ #
93
+ # foo = some_method(nested_call(
94
+ # nested_first_param),
95
+ # second_param)
96
+ #
97
+ # foo = some_method(
98
+ # nested_call(
99
+ # nested_first_param),
100
+ # second_param)
101
+ #
102
+ # some_method nested_call(
103
+ # nested_first_param),
104
+ # second_param
105
+ #
106
+ # # Style: special_for_inner_method_call_in_parentheses
107
+ #
108
+ # # good
109
+ # some_method(
110
+ # first_param,
111
+ # second_param)
112
+ #
113
+ # foo = some_method(
114
+ # first_param,
115
+ # second_param)
116
+ #
117
+ # foo = some_method(nested_call(
118
+ # nested_first_param),
119
+ # second_param)
120
+ #
121
+ # foo = some_method(
122
+ # nested_call(
123
+ # nested_first_param),
124
+ # second_param)
125
+ #
126
+ # some_method nested_call(
127
+ # nested_first_param),
128
+ # second_param
129
+ #
21
130
  class FirstParameterIndentation < Cop
22
131
  include Alignment
23
132
  include ConfigurableEnforcedStyle
@@ -65,6 +174,7 @@ module RuboCop
65
174
 
66
175
  def special_inner_call_indentation?(node)
67
176
  return false if style == :consistent
177
+ return true if style == :consistent_relative_to_receiver
68
178
 
69
179
  parent = node.parent
70
180
 
@@ -66,7 +66,7 @@ module RuboCop
66
66
  return if node.multiline?
67
67
  return unless bracket_method?(node)
68
68
  tokens = tokens(node)
69
- left_token = left_ref_bracket(tokens)
69
+ left_token = left_ref_bracket(node, tokens)
70
70
  return unless left_token
71
71
  right_token = closing_bracket(tokens, left_token)
72
72
 
@@ -101,7 +101,7 @@ module RuboCop
101
101
 
102
102
  def reference_brackets(node)
103
103
  tokens = tokens(node)
104
- left = left_ref_bracket(tokens)
104
+ left = left_ref_bracket(node, tokens)
105
105
  [left, closing_bracket(tokens, left)]
106
106
  end
107
107
 
@@ -110,8 +110,12 @@ module RuboCop
110
110
  BRACKET_METHODS.include?(method)
111
111
  end
112
112
 
113
- def left_ref_bracket(tokens)
114
- tokens.reverse.find(&:left_ref_bracket?)
113
+ def left_ref_bracket(node, tokens)
114
+ if node.method?(:[]=)
115
+ tokens.find(&:left_ref_bracket?)
116
+ else
117
+ tokens.reverse.find(&:left_ref_bracket?)
118
+ end
115
119
  end
116
120
 
117
121
  def closing_bracket(tokens, opening_bracket)
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ #
7
+ # This cop emulates the following Ruby warnings in Ruby 2.6.
8
+ #
9
+ # % cat example.rb
10
+ # ERB.new('hi', nil, '-', '@output_buffer')
11
+ # % ruby -rerb example.rb
12
+ # example.rb:1: warning: Passing safe_level with the 2nd argument of
13
+ # ERB.new is deprecated. Do not use it, and specify other arguments as
14
+ # keyword arguments.
15
+ # example.rb:1: warning: Passing trim_mode with the 3rd argument of
16
+ # ERB.new is deprecated. Use keyword argument like
17
+ # ERB.new(str, trim_mode:...) instead.
18
+ # example.rb:1: warning: Passing eoutvar with the 4th argument of ERB.new
19
+ # is deprecated. Use keyword argument like ERB.new(str, eoutvar: ...)
20
+ # instead.
21
+ #
22
+ # Now non-keyword arguments other than first one are softly deprecated
23
+ # and will be removed when Ruby 2.5 becomes EOL.
24
+ # `ERB.new` with non-keyword arguments is deprecated since ERB 2.2.0.
25
+ # Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.
26
+ # This cop identifies places where `ERB.new(str, trim_mode, eoutvar)` can
27
+ # be replaced by `ERB.new(str, :trim_mode: trim_mode, eoutvar: eoutvar)`.
28
+ #
29
+ # @example
30
+ # # Target codes supports Ruby 2.6 and higher only
31
+ # # bad
32
+ # ERB.new(str, nil, '-', '@output_buffer')
33
+ #
34
+ # # good
35
+ # ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')
36
+ #
37
+ # # Target codes supports Ruby 2.5 and lower only
38
+ # # good
39
+ # ERB.new(str, nil, '-', '@output_buffer')
40
+ #
41
+ # # Target codes supports Ruby 2.6, 2.5 and lower
42
+ # # bad
43
+ # ERB.new(str, nil, '-', '@output_buffer')
44
+ #
45
+ # # good
46
+ # # Ruby standard library style
47
+ # # https://github.com/ruby/ruby/commit/3406c5d
48
+ # if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
49
+ # ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')
50
+ # else
51
+ # ERB.new(str, nil, '-', '@output_buffer')
52
+ # end
53
+ #
54
+ # # good
55
+ # # Use `RUBY_VERSION` style
56
+ # if RUBY_VERSION >= '2.6'
57
+ # ERB.new(str, trim_mode: '-', eoutvar: '@output_buffer')
58
+ # else
59
+ # ERB.new(str, nil, '-', '@output_buffer')
60
+ # end
61
+ #
62
+ class ErbNewArguments < Cop
63
+ extend TargetRubyVersion
64
+
65
+ minimum_target_ruby_version 2.6
66
+
67
+ MESSAGES = [
68
+ 'Passing safe_level with the 2nd argument of `ERB.new` is ' \
69
+ 'deprecated. Do not use it, and specify other arguments as ' \
70
+ 'keyword arguments.',
71
+ 'Passing trim_mode with the 3rd argument of `ERB.new` is ' \
72
+ 'deprecated. Use keyword argument like ' \
73
+ '`ERB.new(str, trim_mode: %<arg_value>s)` instead.',
74
+ 'Passing eoutvar with the 4th argument of `ERB.new` is ' \
75
+ 'deprecated. Use keyword argument like ' \
76
+ '`ERB.new(str, eoutvar: %<arg_value>s)` instead.'
77
+ ].freeze
78
+
79
+ def_node_matcher :erb_new_with_non_keyword_arguments, <<-PATTERN
80
+ (send
81
+ (const {nil? cbase} :ERB) :new $...)
82
+ PATTERN
83
+
84
+ def on_send(node)
85
+ erb_new_with_non_keyword_arguments(node) do |arguments|
86
+ return if correct_arguments?(arguments)
87
+
88
+ 1.upto(3) do |i|
89
+ next if !arguments[i] || arguments[i].hash_type?
90
+
91
+ message = format(MESSAGES[i - 1], arg_value: arguments[i].source)
92
+
93
+ add_offense(
94
+ node, location: arguments[i].source_range, message: message
95
+ )
96
+ end
97
+ end
98
+ end
99
+
100
+ def correct_arguments?(arguments)
101
+ arguments.size == 1 ||
102
+ arguments.size == 2 && arguments[1].hash_type?
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -50,6 +50,10 @@ module RuboCop
50
50
 
51
51
  def autocorrected_value(node)
52
52
  case node.type
53
+ when :int
54
+ node.children.last.to_i.to_s
55
+ when :float
56
+ node.children.last.to_f.to_s
53
57
  when :str
54
58
  node.children.last
55
59
  when :sym
@@ -38,14 +38,6 @@ module RuboCop
38
38
 
39
39
  private
40
40
 
41
- def str_content(node)
42
- if node.str_type?
43
- node.children[0]
44
- else
45
- node.children.map { |c| str_content(c) }.join
46
- end
47
- end
48
-
49
41
  def contains_percent_literals?(node)
50
42
  node.each_child_node.any? do |child|
51
43
  literal = child.children.first.to_s.scrub
@@ -62,7 +62,7 @@ module RuboCop
62
62
  literal = value.children.first.to_s.scrub
63
63
 
64
64
  # To avoid likely false positives (e.g. a single ' or ")
65
- next if literal.gsub(/[^\p{Alnum}]/, '').empty?
65
+ next if literal.gsub(/[^[[:alnum:]]]/, '').empty?
66
66
 
67
67
  QUOTES_AND_COMMAS.any? { |pat| literal =~ pat }
68
68
  end
@@ -55,7 +55,7 @@ module RuboCop
55
55
  literal = child.children.first
56
56
 
57
57
  # To avoid likely false positives (e.g. a single ' or ")
58
- next if literal.to_s.gsub(/[^\p{Alnum}]/, '').empty?
58
+ next if literal.to_s.gsub(/[^[[:alnum:]]]/, '').empty?
59
59
 
60
60
  patterns.any? { |pat| literal =~ pat }
61
61
  end
@@ -31,7 +31,10 @@ module RuboCop
31
31
  ' after safe navigation operator.'.freeze
32
32
 
33
33
  def_node_matcher :bad_method?, <<-PATTERN
34
+ {
34
35
  (send $(csend ...) $_ ...)
36
+ (send $(block (csend ...) ...) $_ ...)
37
+ }
35
38
  PATTERN
36
39
 
37
40
  minimum_target_ruby_version 2.3
@@ -27,6 +27,9 @@ module RuboCop
27
27
  # foo&.bar && (foobar.baz || foo&.baz)
28
28
  #
29
29
  class SafeNavigationConsistency < Cop
30
+ include IgnoredNode
31
+ include NilMethods
32
+
30
33
  MSG = 'Ensure that safe navigation is used consistently ' \
31
34
  'inside of `&&` and `||`.'.freeze
32
35
 
@@ -42,15 +45,16 @@ module RuboCop
42
45
  safe_nav_receiver = node.receiver
43
46
 
44
47
  method_calls = conditions.select(&:send_type?)
45
- unsafe_method_calls = method_calls.select do |method_call|
46
- safe_nav_receiver == method_call.receiver
47
- end
48
+ unsafe_method_calls =
49
+ unsafe_method_calls(method_calls, safe_nav_receiver)
48
50
 
49
51
  unsafe_method_calls.each do |unsafe_method_call|
50
52
  location =
51
53
  node.loc.expression.join(unsafe_method_call.loc.expression)
52
54
  add_offense(unsafe_method_call,
53
55
  location: location)
56
+
57
+ ignore_node(unsafe_method_call)
54
58
  end
55
59
  end
56
60
 
@@ -69,11 +73,20 @@ module RuboCop
69
73
  unless parent &&
70
74
  (AST::Node::OPERATOR_KEYWORDS.include?(parent.type) ||
71
75
  (parent.begin_type? &&
76
+ parent.parent &&
72
77
  AST::Node::OPERATOR_KEYWORDS.include?(parent.parent.type)))
73
78
  return node
74
79
  end
75
80
  top_conditional_ancestor(parent)
76
81
  end
82
+
83
+ def unsafe_method_calls(method_calls, safe_nav_receiver)
84
+ method_calls.select do |method_call|
85
+ safe_nav_receiver == method_call.receiver &&
86
+ !nil_methods.include?(method_call.method_name) &&
87
+ !ignored_node?(method_call)
88
+ end
89
+ end
77
90
  end
78
91
  end
79
92
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ #
7
+ # This cop emulates the following Ruby warnings in Ruby 2.6.
8
+ #
9
+ # % ruby -we "def m(a) end; h = {foo: 1}; m(**h)"
10
+ # -e:1: warning: passing splat keyword arguments as a single Hash to `m'
11
+ #
12
+ # It checks for use of splat keyword arguments as a single Hash.
13
+ #
14
+ # @example
15
+ # # bad
16
+ # do_something(**arguments)
17
+ #
18
+ # # good
19
+ # do_something(arguments)
20
+ #
21
+ class SplatKeywordArguments < Cop
22
+ MSG = 'Do not use splat keyword arguments as a single Hash.'.freeze
23
+
24
+ def on_send(node)
25
+ node.arguments.each do |argument|
26
+ next unless argument.hash_type?
27
+
28
+ argument.children.each do |element|
29
+ add_offense(element) if element.kwsplat_type?
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end