rubocop 0.71.0 → 0.72.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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -8
  3. data/config/default.yml +42 -484
  4. data/lib/rubocop.rb +5 -53
  5. data/lib/rubocop/ast/builder.rb +2 -0
  6. data/lib/rubocop/ast/node.rb +1 -1
  7. data/lib/rubocop/ast/node/float_node.rb +12 -0
  8. data/lib/rubocop/ast/node/int_node.rb +12 -0
  9. data/lib/rubocop/ast/node/mixin/numeric_node.rb +21 -0
  10. data/lib/rubocop/ast/node/resbody_node.rb +1 -6
  11. data/lib/rubocop/cached_data.rb +1 -1
  12. data/lib/rubocop/config.rb +34 -5
  13. data/lib/rubocop/config_loader.rb +2 -6
  14. data/lib/rubocop/config_loader_resolver.rb +0 -14
  15. data/lib/rubocop/cop/cop.rb +0 -4
  16. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +55 -0
  17. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  18. data/lib/rubocop/cop/layout/indent_first_argument.rb +6 -2
  19. data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
  20. data/lib/rubocop/cop/layout/indent_heredoc.rb +0 -1
  21. data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
  22. data/lib/rubocop/cop/layout/indentation_width.rb +8 -4
  23. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  24. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +21 -20
  25. data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
  26. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -1
  27. data/lib/rubocop/cop/style/float_division.rb +94 -0
  28. data/lib/rubocop/cop/style/format_string.rb +7 -3
  29. data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
  30. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -1
  31. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  32. data/lib/rubocop/cop/style/ternary_parentheses.rb +12 -2
  33. data/lib/rubocop/cop/style/word_array.rb +2 -2
  34. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -1
  35. data/lib/rubocop/options.rb +0 -2
  36. data/lib/rubocop/processed_source.rb +2 -1
  37. data/lib/rubocop/rspec/cop_helper.rb +0 -1
  38. data/lib/rubocop/rspec/shared_contexts.rb +0 -17
  39. data/lib/rubocop/rspec/support.rb +0 -1
  40. data/lib/rubocop/runner.rb +0 -17
  41. data/lib/rubocop/version.rb +1 -1
  42. data/lib/rubocop/yaml_duplication_checker.rb +8 -2
  43. metadata +8 -91
  44. data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
  45. data/lib/rubocop/cop/rails/action_filter.rb +0 -117
  46. data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
  47. data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
  48. data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
  49. data/lib/rubocop/cop/rails/application_job.rb +0 -40
  50. data/lib/rubocop/cop/rails/application_record.rb +0 -40
  51. data/lib/rubocop/cop/rails/assert_not.rb +0 -44
  52. data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
  53. data/lib/rubocop/cop/rails/blank.rb +0 -164
  54. data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
  55. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
  56. data/lib/rubocop/cop/rails/date.rb +0 -161
  57. data/lib/rubocop/cop/rails/delegate.rb +0 -132
  58. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
  59. data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
  60. data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
  61. data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
  62. data/lib/rubocop/cop/rails/exit.rb +0 -67
  63. data/lib/rubocop/cop/rails/file_path.rb +0 -108
  64. data/lib/rubocop/cop/rails/find_by.rb +0 -55
  65. data/lib/rubocop/cop/rails/find_each.rb +0 -51
  66. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
  67. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
  68. data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
  69. data/lib/rubocop/cop/rails/http_status.rb +0 -179
  70. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
  71. data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
  72. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
  73. data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
  74. data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
  75. data/lib/rubocop/cop/rails/output.rb +0 -49
  76. data/lib/rubocop/cop/rails/output_safety.rb +0 -99
  77. data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
  78. data/lib/rubocop/cop/rails/presence.rb +0 -124
  79. data/lib/rubocop/cop/rails/present.rb +0 -153
  80. data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
  81. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
  82. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
  83. data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
  84. data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
  85. data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
  86. data/lib/rubocop/cop/rails/request_referer.rb +0 -56
  87. data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
  88. data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
  89. data/lib/rubocop/cop/rails/save_bang.rb +0 -316
  90. data/lib/rubocop/cop/rails/scope_args.rb +0 -29
  91. data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
  92. data/lib/rubocop/cop/rails/time_zone.rb +0 -238
  93. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
  94. data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
  95. data/lib/rubocop/cop/rails/validation.rb +0 -109
  96. data/lib/rubocop/rspec/shared_examples.rb +0 -59
@@ -83,7 +83,7 @@ module RuboCop
83
83
 
84
84
  check_indentation(end_loc, node.body)
85
85
 
86
- return unless indentation_consistency_style == 'rails'
86
+ return unless indented_internal_methods_style?
87
87
 
88
88
  check_members(end_loc, [node.body])
89
89
  end
@@ -155,8 +155,8 @@ module RuboCop
155
155
 
156
156
  return unless members.any? && members.first.begin_type?
157
157
 
158
- if indentation_consistency_style == 'rails'
159
- check_members_for_rails_style(members)
158
+ if indentation_consistency_style == 'indented_internal_methods'
159
+ check_members_for_indented_internal_methods_style(members)
160
160
  else
161
161
  members.first.children.each do |member|
162
162
  next if member.send_type? && member.access_modifier?
@@ -176,7 +176,7 @@ module RuboCop
176
176
  end
177
177
  end
178
178
 
179
- def check_members_for_rails_style(members)
179
+ def check_members_for_indented_internal_methods_style(members)
180
180
  each_member(members) do |member, previous_modifier|
181
181
  check_indentation(previous_modifier, member,
182
182
  indentation_consistency_style)
@@ -195,6 +195,10 @@ module RuboCop
195
195
  end
196
196
  end
197
197
 
198
+ def indented_internal_methods_style?
199
+ indentation_consistency_style == 'indented_internal_methods'
200
+ end
201
+
198
202
  def indentation_consistency_style
199
203
  config.for_cop('Layout/IndentationConsistency')['EnforcedStyle']
200
204
  end
@@ -64,7 +64,7 @@ module RuboCop
64
64
 
65
65
  def date_time_object?(node)
66
66
  child = node
67
- while child.send_type?
67
+ while child&.send_type?
68
68
  return true if datetime? child
69
69
 
70
70
  child = child.children[0]
@@ -57,24 +57,20 @@ module RuboCop
57
57
  MSG = 'Use `%<preferred>s` instead of `%<bad>s`.'
58
58
 
59
59
  def on_resbody(node)
60
- exception_type, @exception_name = *node
61
- return unless exception_type || @exception_name
62
-
63
- @exception_name ||= exception_type.children.first
64
- return if @exception_name.const_type? ||
65
- variable_name == preferred_name
60
+ name = variable_name(node)
61
+ return unless name
62
+ return if preferred_name(name).to_sym == name
66
63
 
67
64
  add_offense(node, location: offense_range(node))
68
65
  end
69
66
 
70
67
  def autocorrect(node)
71
68
  lambda do |corrector|
72
- offending_name = node.exception_variable.children.first
69
+ offending_name = variable_name(node)
70
+ preferred_name = preferred_name(offending_name)
73
71
  corrector.replace(offense_range(node), preferred_name)
74
72
 
75
- return unless node.body
76
-
77
- node.body.each_descendant(:lvar) do |var|
73
+ node.body&.each_descendant(:lvar) do |var|
78
74
  next unless var.children.first == offending_name
79
75
 
80
76
  corrector.replace(var.loc.expression, preferred_name)
@@ -89,21 +85,26 @@ module RuboCop
89
85
  variable.loc.expression
90
86
  end
91
87
 
92
- def preferred_name
93
- name = cop_config.fetch('PreferredName', 'e')
94
- variable_name.to_s.start_with?('_') ? "_#{name}" : name
88
+ def preferred_name(variable_name)
89
+ preferred_name = cop_config.fetch('PreferredName', 'e')
90
+ if variable_name.to_s.start_with?('_')
91
+ "_#{preferred_name}"
92
+ else
93
+ preferred_name
94
+ end
95
95
  end
96
96
 
97
- def variable_name
98
- location.source
99
- end
97
+ def variable_name(node)
98
+ asgn_node = node.exception_variable
99
+ return unless asgn_node
100
100
 
101
- def location
102
- @exception_name.loc.expression
101
+ asgn_node.children.last
103
102
  end
104
103
 
105
- def message(_node = nil)
106
- format(MSG, preferred: preferred_name, bad: variable_name)
104
+ def message(node)
105
+ offending_name = variable_name(node)
106
+ preferred_name = preferred_name(offending_name)
107
+ format(MSG, preferred: preferred_name, bad: offending_name)
107
108
  end
108
109
  end
109
110
  end
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # This cop checks for comments put on the same line as some keywords.
7
7
  # These keywords are: `begin`, `class`, `def`, `end`, `module`.
8
8
  #
9
- # Note that some comments (`:nodoc:`, `:yields:, and `rubocop:disable`)
9
+ # Note that some comments (`:nodoc:`, `:yields:`, and `rubocop:disable`)
10
10
  # are allowed.
11
11
  #
12
12
  # @example
@@ -596,7 +596,8 @@ module RuboCop
596
596
 
597
597
  remove_whitespace_in_branches(corrector, branch, condition, column)
598
598
 
599
- branch_else = branch.parent.loc.else
599
+ return unless (branch_else = branch.parent.loc.else)
600
+
600
601
  corrector.remove_preceding(branch_else, branch_else.column - column)
601
602
  end
602
603
  end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for division with integers coerced to floats.
7
+ # It is recommended to either always use `fdiv` or coerce one side only.
8
+ # This cop also provides other options for code consistency.
9
+ #
10
+ # @example EnforcedStyle: single_coerce (default)
11
+ # # bad
12
+ # a.to_f / b.to_f
13
+ #
14
+ # # good
15
+ # a.to_f / b
16
+ # a / b.to_f
17
+ #
18
+ # @example EnforcedStyle: left_coerce
19
+ # # bad
20
+ # a / b.to_f
21
+ # a.to_f / b.to_f
22
+ #
23
+ # # good
24
+ # a.to_f / b
25
+ #
26
+ # @example EnforcedStyle: right_coerce
27
+ # # bad
28
+ # a.to_f / b
29
+ # a.to_f / b.to_f
30
+ #
31
+ # # good
32
+ # a / b.to_f
33
+ #
34
+ # @example EnforcedStyle: fdiv
35
+ # # bad
36
+ # a / b.to_f
37
+ # a.to_f / b
38
+ # a.to_f / b.to_f
39
+ #
40
+ # # good
41
+ # a.fdiv(b)
42
+ class FloatDivision < Cop
43
+ include ConfigurableEnforcedStyle
44
+
45
+ def_node_matcher :right_coerce?, <<-PATTERN
46
+ (send _ :/ (send _ :to_f))
47
+ PATTERN
48
+ def_node_matcher :left_coerce?, <<-PATTERN
49
+ (send (send _ :to_f) :/ _)
50
+ PATTERN
51
+ def_node_matcher :both_coerce?, <<-PATTERN
52
+ (send (send _ :to_f) :/ (send _ :to_f))
53
+ PATTERN
54
+ def_node_matcher :any_coerce?, <<-PATTERN
55
+ {(send _ :/ (send _ :to_f)) (send (send _ :to_f) :/ _)}
56
+ PATTERN
57
+
58
+ def on_send(node)
59
+ add_offense(node) if offense_condition?(node)
60
+ end
61
+
62
+ private
63
+
64
+ def offense_condition?(node)
65
+ case style
66
+ when :left_coerce
67
+ right_coerce?(node)
68
+ when :right_coerce
69
+ left_coerce?(node)
70
+ when :single_coerce
71
+ both_coerce?(node)
72
+ when :fdiv
73
+ any_coerce?(node)
74
+ else
75
+ false
76
+ end
77
+ end
78
+
79
+ def message(_node)
80
+ case style
81
+ when :left_coerce
82
+ 'Prefer using `.to_f` on the left side.'
83
+ when :right_coerce
84
+ 'Prefer using `.to_f` on the right side.'
85
+ when :single_coerce
86
+ 'Prefer using `.to_f` on one side only.'
87
+ when :fdiv
88
+ 'Prefer using `fdiv` for float divisions.'
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -48,6 +48,10 @@ module RuboCop
48
48
  }
49
49
  PATTERN
50
50
 
51
+ def_node_matcher :variable_argument?, <<-PATTERN
52
+ (send {str dstr} :% {send_type? lvar_type?})
53
+ PATTERN
54
+
51
55
  def on_send(node)
52
56
  formatter(node) do |selector|
53
57
  detected_style = selector == :% ? :percent : selector
@@ -70,10 +74,10 @@ module RuboCop
70
74
  end
71
75
 
72
76
  def autocorrect(node)
73
- lambda do |corrector|
74
- detected_method = node.method_name
77
+ return if variable_argument?(node)
75
78
 
76
- case detected_method
79
+ lambda do |corrector|
80
+ case node.method_name
77
81
  when :%
78
82
  autocorrect_from_percent(corrector, node)
79
83
  when :format, :sprintf
@@ -27,6 +27,37 @@ module RuboCop
27
27
  # else
28
28
  # action_c
29
29
  # end
30
+ #
31
+ # @example AllowIfModifier: false (default)
32
+ # # bad
33
+ # if condition_a
34
+ # action_a
35
+ # else
36
+ # action_b if condition_b
37
+ # end
38
+ #
39
+ # # good
40
+ # if condition_a
41
+ # action_a
42
+ # elsif condition_b
43
+ # action_b
44
+ # end
45
+ #
46
+ # @example AllowIfModifier: true
47
+ # # good
48
+ # if condition_a
49
+ # action_a
50
+ # else
51
+ # action_b if condition_b
52
+ # end
53
+ #
54
+ # # good
55
+ # if condition_a
56
+ # action_a
57
+ # elsif condition_b
58
+ # action_b
59
+ # end
60
+ #
30
61
  class IfInsideElse < Cop
31
62
  MSG = 'Convert `if` nested inside `else` to `elsif`.'
32
63
 
@@ -36,9 +67,20 @@ module RuboCop
36
67
  else_branch = node.else_branch
37
68
 
38
69
  return unless else_branch&.if_type? && else_branch&.if?
70
+ return if allow_if_modifier_in_else_branch?(else_branch)
39
71
 
40
72
  add_offense(else_branch, location: :keyword)
41
73
  end
74
+
75
+ private
76
+
77
+ def allow_if_modifier_in_else_branch?(else_branch)
78
+ allow_if_modifier? && else_branch&.modifier_form?
79
+ end
80
+
81
+ def allow_if_modifier?
82
+ cop_config['AllowIfModifier']
83
+ end
42
84
  end
43
85
  end
44
86
  end
@@ -348,7 +348,8 @@ module RuboCop
348
348
  end
349
349
 
350
350
  def ambigious_literal?(node)
351
- splat?(node) || ternary_if?(node) || regexp_slash_literal?(node)
351
+ splat?(node) || ternary_if?(node) || regexp_slash_literal?(node) ||
352
+ unary_literal?(node)
352
353
  end
353
354
 
354
355
  def splat?(node)
@@ -371,6 +372,11 @@ module RuboCop
371
372
  node.regexp_type? && node.loc.begin.source == '/'
372
373
  end
373
374
 
375
+ def unary_literal?(node)
376
+ node.numeric_type? && node.sign? ||
377
+ node.parent&.send_type? && node.parent&.unary_operation?
378
+ end
379
+
374
380
  def assigned_before?(node, target)
375
381
  node.assignment? &&
376
382
  node.loc.operator.begin < target.loc.begin
@@ -224,7 +224,7 @@ module RuboCop
224
224
  end
225
225
 
226
226
  def method_called?(send_node)
227
- send_node.parent&.send_type?
227
+ send_node&.parent&.send_type?
228
228
  end
229
229
 
230
230
  def begin_range(node, method_call)
@@ -108,7 +108,7 @@ module RuboCop
108
108
  end
109
109
 
110
110
  def non_complex_send?(node)
111
- return false unless node.send_type?
111
+ return false unless node.call_type?
112
112
 
113
113
  !node.operator_method? || node.method?(:[])
114
114
  end
@@ -149,7 +149,8 @@ module RuboCop
149
149
 
150
150
  def unsafe_autocorrect?(condition)
151
151
  condition.children.any? do |child|
152
- unparenthesized_method_call?(child)
152
+ unparenthesized_method_call?(child) ||
153
+ below_ternary_precedence?(child)
153
154
  end
154
155
  end
155
156
 
@@ -157,6 +158,15 @@ module RuboCop
157
158
  method_name(child) =~ /^[a-z]/i && !child.parenthesized?
158
159
  end
159
160
 
161
+ def below_ternary_precedence?(child)
162
+ # Handle English "or", e.g. 'foo or bar ? a : b'
163
+ (child.or_type? && child.semantic_operator?) ||
164
+ # Handle English "and", e.g. 'foo and bar ? a : b'
165
+ (child.and_type? && child.semantic_operator?) ||
166
+ # Handle English "not", e.g. 'not foo ? a : b'
167
+ (child.send_type? && child.prefix_not?)
168
+ end
169
+
160
170
  def_node_matcher :method_name, <<-PATTERN
161
171
  {($:defined? (send nil? _) ...)
162
172
  (send {_ nil?} $_ _ ...)}
@@ -71,8 +71,8 @@ module RuboCop
71
71
 
72
72
  def complex_content?(strings)
73
73
  strings.any? do |s|
74
- string = s.str_content
75
- !string.dup.force_encoding(::Encoding::UTF_8).valid_encoding? ||
74
+ string = s.str_content.dup.force_encoding(::Encoding::UTF_8)
75
+ !string.valid_encoding? ||
76
76
  string !~ word_regex || string =~ / /
77
77
  end
78
78
  end
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # by a predicate method, such as receiver.length == 0,
8
8
  # receiver.length > 0, receiver.length != 0,
9
9
  # receiver.length < 1 and receiver.size == 0 that can be
10
- # replaced by receiver.empty? and !receiver.empty.
10
+ # replaced by receiver.empty? and !receiver.empty?.
11
11
  #
12
12
  # @example
13
13
  # # bad
@@ -159,7 +159,6 @@ module RuboCop
159
159
  option(opts, '-D', '--[no-]display-cop-names')
160
160
  option(opts, '-E', '--extra-details')
161
161
  option(opts, '-S', '--display-style-guide')
162
- option(opts, '-R', '--rails')
163
162
  option(opts, '-a', '--auto-correct')
164
163
  option(opts, '--ignore-disable-comments')
165
164
 
@@ -429,7 +428,6 @@ module RuboCop
429
428
  'Default is true.'],
430
429
  display_style_guide: 'Display style guide URLs in offense messages.',
431
430
  extra_details: 'Display extra details in offense messages.',
432
- rails: 'Run extra Rails cops.',
433
431
  lint: 'Run only lint cops.',
434
432
  safe: 'Run only safe cops.',
435
433
  list_target_files: 'List all files RuboCop will inspect.',
@@ -187,7 +187,8 @@ module RuboCop
187
187
  require 'parser/ruby27'
188
188
  Parser::Ruby27
189
189
  else
190
- raise ArgumentError, "Unknown Ruby version: #{ruby_version.inspect}"
190
+ raise ArgumentError,
191
+ "RuboCop found unknown Ruby version: #{ruby_version.inspect}"
191
192
  end
192
193
  end
193
194
  # rubocop:enable Metrics/MethodLength
@@ -7,7 +7,6 @@ module CopHelper
7
7
  extend RSpec::SharedContext
8
8
 
9
9
  let(:ruby_version) { 2.3 }
10
- let(:enabled_rails) { false }
11
10
  let(:rails_version) { false }
12
11
 
13
12
  def inspect_source_file(source)
@@ -47,7 +47,6 @@ RSpec.shared_context 'config', :config do
47
47
  end
48
48
 
49
49
  hash = { 'AllCops' => { 'TargetRubyVersion' => ruby_version } }
50
- hash['Rails'] = { 'Enabled' => true } if enabled_rails
51
50
  hash['AllCops']['TargetRailsVersion'] = rails_version if rails_version
52
51
  if respond_to?(:cop_config)
53
52
  cop_name = described_class.cop_name
@@ -77,19 +76,3 @@ end
77
76
  RSpec.shared_context 'ruby 2.6', :ruby26 do
78
77
  let(:ruby_version) { 2.6 }
79
78
  end
80
-
81
- RSpec.shared_context 'with Rails', :enabled_rails do
82
- let(:enabled_rails) { true }
83
- end
84
-
85
- RSpec.shared_context 'with Rails 3', :rails3 do
86
- let(:rails_version) { 3.0 }
87
- end
88
-
89
- RSpec.shared_context 'with Rails 4', :rails4 do
90
- let(:rails_version) { 4.0 }
91
- end
92
-
93
- RSpec.shared_context 'with Rails 5', :rails5 do
94
- let(:rails_version) { 5.0 }
95
- end