rubocop 0.67.2 → 0.68.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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +86 -233
  4. data/exe/rubocop +0 -12
  5. data/lib/rubocop.rb +13 -30
  6. data/lib/rubocop/ast/builder.rb +4 -0
  7. data/lib/rubocop/ast/node/alias_node.rb +24 -0
  8. data/lib/rubocop/ast/node/class_node.rb +31 -0
  9. data/lib/rubocop/ast/node/module_node.rb +24 -0
  10. data/lib/rubocop/ast/node/range_node.rb +7 -0
  11. data/lib/rubocop/ast/node/resbody_node.rb +12 -0
  12. data/lib/rubocop/ast/node/self_class_node.rb +24 -0
  13. data/lib/rubocop/cli.rb +40 -4
  14. data/lib/rubocop/config.rb +9 -7
  15. data/lib/rubocop/config_loader.rb +48 -7
  16. data/lib/rubocop/config_loader_resolver.rb +5 -4
  17. data/lib/rubocop/cop/commissioner.rb +24 -0
  18. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +18 -6
  19. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +12 -14
  20. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +9 -20
  21. data/lib/rubocop/cop/layout/align_arguments.rb +93 -0
  22. data/lib/rubocop/cop/layout/align_parameters.rb +57 -33
  23. data/lib/rubocop/cop/layout/class_structure.rb +5 -5
  24. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +6 -8
  25. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +3 -6
  26. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +1 -2
  27. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -0
  28. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +292 -0
  29. data/lib/rubocop/cop/layout/{first_parameter_indentation.rb → indent_first_argument.rb} +11 -12
  30. data/lib/rubocop/cop/layout/{indent_array.rb → indent_first_array_element.rb} +2 -2
  31. data/lib/rubocop/cop/layout/{indent_hash.rb → indent_first_hash_element.rb} +2 -2
  32. data/lib/rubocop/cop/layout/indent_first_parameter.rb +96 -0
  33. data/lib/rubocop/cop/layout/indentation_width.rb +4 -16
  34. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -4
  35. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -16
  36. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -2
  37. data/lib/rubocop/cop/lint/duplicate_methods.rb +6 -8
  38. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -8
  39. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +157 -0
  40. data/lib/rubocop/cop/lint/inherit_exception.rb +3 -4
  41. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +18 -1
  42. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -5
  43. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +25 -5
  44. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -6
  45. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -2
  46. data/lib/rubocop/cop/message_annotator.rb +1 -0
  47. data/lib/rubocop/cop/metrics/line_length.rb +139 -28
  48. data/lib/rubocop/cop/metrics/perceived_complexity.rb +3 -4
  49. data/lib/rubocop/cop/mixin/check_line_breakable.rb +190 -0
  50. data/lib/rubocop/cop/mixin/{array_hash_indentation.rb → multiline_element_indentation.rb} +3 -2
  51. data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -7
  52. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +33 -4
  53. data/lib/rubocop/cop/rails/active_record_override.rb +23 -8
  54. data/lib/rubocop/cop/rails/delegate.rb +5 -8
  55. data/lib/rubocop/cop/rails/environment_comparison.rb +5 -3
  56. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  57. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +3 -3
  58. data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
  59. data/lib/rubocop/cop/rails/skips_model_validations.rb +6 -7
  60. data/lib/rubocop/cop/rails/time_zone.rb +3 -10
  61. data/lib/rubocop/cop/rails/validation.rb +3 -0
  62. data/lib/rubocop/cop/registry.rb +3 -3
  63. data/lib/rubocop/cop/style/alias.rb +13 -7
  64. data/lib/rubocop/cop/style/block_delimiters.rb +20 -0
  65. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -21
  66. data/lib/rubocop/cop/style/class_methods.rb +16 -24
  67. data/lib/rubocop/cop/style/conditional_assignment.rb +20 -49
  68. data/lib/rubocop/cop/style/documentation.rb +3 -7
  69. data/lib/rubocop/cop/style/format_string.rb +18 -21
  70. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  71. data/lib/rubocop/cop/style/inverse_methods.rb +4 -0
  72. data/lib/rubocop/cop/style/lambda.rb +12 -8
  73. data/lib/rubocop/cop/style/mixin_grouping.rb +8 -10
  74. data/lib/rubocop/cop/style/module_function.rb +2 -3
  75. data/lib/rubocop/cop/style/next.rb +10 -14
  76. data/lib/rubocop/cop/style/one_line_conditional.rb +5 -3
  77. data/lib/rubocop/cop/style/optional_arguments.rb +1 -4
  78. data/lib/rubocop/cop/style/random_with_offset.rb +44 -47
  79. data/lib/rubocop/cop/style/redundant_return.rb +6 -14
  80. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  81. data/lib/rubocop/cop/style/safe_navigation.rb +3 -0
  82. data/lib/rubocop/cop/style/struct_inheritance.rb +2 -3
  83. data/lib/rubocop/cop/style/symbol_proc.rb +20 -40
  84. data/lib/rubocop/cop/style/unless_else.rb +1 -2
  85. data/lib/rubocop/cop/style/yoda_condition.rb +8 -7
  86. data/lib/rubocop/cop/util.rb +2 -4
  87. data/lib/rubocop/file_finder.rb +5 -10
  88. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -0
  89. data/lib/rubocop/node_pattern.rb +304 -170
  90. data/lib/rubocop/options.rb +4 -1
  91. data/lib/rubocop/rspec/shared_contexts.rb +3 -0
  92. data/lib/rubocop/version.rb +1 -1
  93. data/lib/rubocop/yaml_duplication_checker.rb +1 -1
  94. metadata +26 -50
  95. data/lib/rubocop/cop/performance/caller.rb +0 -69
  96. data/lib/rubocop/cop/performance/case_when_splat.rb +0 -177
  97. data/lib/rubocop/cop/performance/casecmp.rb +0 -108
  98. data/lib/rubocop/cop/performance/chain_array_allocation.rb +0 -78
  99. data/lib/rubocop/cop/performance/compare_with_block.rb +0 -122
  100. data/lib/rubocop/cop/performance/count.rb +0 -102
  101. data/lib/rubocop/cop/performance/detect.rb +0 -110
  102. data/lib/rubocop/cop/performance/double_start_end_with.rb +0 -94
  103. data/lib/rubocop/cop/performance/end_with.rb +0 -56
  104. data/lib/rubocop/cop/performance/fixed_size.rb +0 -97
  105. data/lib/rubocop/cop/performance/flat_map.rb +0 -78
  106. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +0 -99
  107. data/lib/rubocop/cop/performance/open_struct.rb +0 -46
  108. data/lib/rubocop/cop/performance/range_include.rb +0 -50
  109. data/lib/rubocop/cop/performance/redundant_block_call.rb +0 -93
  110. data/lib/rubocop/cop/performance/redundant_match.rb +0 -56
  111. data/lib/rubocop/cop/performance/redundant_merge.rb +0 -183
  112. data/lib/rubocop/cop/performance/regexp_match.rb +0 -265
  113. data/lib/rubocop/cop/performance/reverse_each.rb +0 -42
  114. data/lib/rubocop/cop/performance/size.rb +0 -77
  115. data/lib/rubocop/cop/performance/start_with.rb +0 -59
  116. data/lib/rubocop/cop/performance/string_replacement.rb +0 -173
  117. data/lib/rubocop/cop/performance/times_map.rb +0 -71
  118. data/lib/rubocop/cop/performance/unfreeze_string.rb +0 -50
  119. data/lib/rubocop/cop/performance/uri_default_parser.rb +0 -47
@@ -117,6 +117,8 @@ module RuboCop
117
117
  option(opts, '--no-auto-gen-timestamp') do
118
118
  @options[:no_auto_gen_timestamp] = true
119
119
  end
120
+
121
+ option(opts, '--init')
120
122
  end
121
123
 
122
124
  def add_formatting_options(opts)
@@ -435,7 +437,8 @@ module RuboCop
435
437
  parallel: ['Use available CPUs to execute inspection in',
436
438
  'parallel.'],
437
439
  stdin: ['Pipe source from STDIN, using FILE in offense',
438
- 'reports. This is useful for editor integration.']
440
+ 'reports. This is useful for editor integration.'],
441
+ init: 'Generate a .rubocop.yml file in the current directory.'
439
442
  }.freeze
440
443
  end
441
444
  end
@@ -7,6 +7,7 @@ RSpec.shared_context 'isolated environment', :isolated_environment do
7
7
  around do |example|
8
8
  Dir.mktmpdir do |tmpdir|
9
9
  original_home = ENV['HOME']
10
+ original_xdg_config_home = ENV['XDG_CONFIG_HOME']
10
11
 
11
12
  # Make sure to expand all symlinks in the path first. Otherwise we may
12
13
  # get mismatched pathnames when loading config files later on.
@@ -19,6 +20,7 @@ RSpec.shared_context 'isolated environment', :isolated_environment do
19
20
  virtual_home = File.expand_path(File.join(tmpdir, 'home'))
20
21
  Dir.mkdir(virtual_home)
21
22
  ENV['HOME'] = virtual_home
23
+ ENV.delete('XDG_CONFIG_HOME')
22
24
 
23
25
  working_dir = File.join(tmpdir, 'work')
24
26
  Dir.mkdir(working_dir)
@@ -28,6 +30,7 @@ RSpec.shared_context 'isolated environment', :isolated_environment do
28
30
  end
29
31
  ensure
30
32
  ENV['HOME'] = original_home
33
+ ENV['XDG_CONFIG_HOME'] = original_xdg_config_home
31
34
 
32
35
  RuboCop::FileFinder.root_level = nil
33
36
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.67.2'.freeze
6
+ STRING = '0.68.0'.freeze
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, running on ' \
9
9
  '%<ruby_engine>s %<ruby_version>s %<ruby_platform>s)'.freeze
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module YAMLDuplicationChecker
6
6
  def self.check(yaml_string, filename, &on_duplicated)
7
7
  # Specify filename to display helpful message when it raises an error.
8
- tree = YAML.parse(yaml_string, filename: filename)
8
+ tree = YAML.parse(yaml_string, filename)
9
9
  return unless tree
10
10
 
11
11
  traverse(tree, &on_duplicated)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.67.2
4
+ version: 0.68.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-04-05 00:00:00.000000000 Z
13
+ date: 2019-04-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: jaro_winkler
@@ -60,20 +60,6 @@ dependencies:
60
60
  - - "!="
61
61
  - !ruby/object:Gem::Version
62
62
  version: 2.5.1.1
63
- - !ruby/object:Gem::Dependency
64
- name: psych
65
- requirement: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: 3.1.0
70
- type: :runtime
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: 3.1.0
77
63
  - !ruby/object:Gem::Dependency
78
64
  name: rainbow
79
65
  requirement: !ruby/object:Gem::Requirement
@@ -134,7 +120,7 @@ dependencies:
134
120
  requirements:
135
121
  - - ">="
136
122
  - !ruby/object:Gem::Version
137
- version: 1.3.0
123
+ version: 1.15.0
138
124
  - - "<"
139
125
  - !ruby/object:Gem::Version
140
126
  version: '3.0'
@@ -144,7 +130,7 @@ dependencies:
144
130
  requirements:
145
131
  - - ">="
146
132
  - !ruby/object:Gem::Version
147
- version: 1.3.0
133
+ version: 1.15.0
148
134
  - - "<"
149
135
  - !ruby/object:Gem::Version
150
136
  version: '3.0'
@@ -184,12 +170,14 @@ files:
184
170
  - lib/rubocop.rb
185
171
  - lib/rubocop/ast/builder.rb
186
172
  - lib/rubocop/ast/node.rb
173
+ - lib/rubocop/ast/node/alias_node.rb
187
174
  - lib/rubocop/ast/node/and_node.rb
188
175
  - lib/rubocop/ast/node/args_node.rb
189
176
  - lib/rubocop/ast/node/array_node.rb
190
177
  - lib/rubocop/ast/node/block_node.rb
191
178
  - lib/rubocop/ast/node/break_node.rb
192
179
  - lib/rubocop/ast/node/case_node.rb
180
+ - lib/rubocop/ast/node/class_node.rb
193
181
  - lib/rubocop/ast/node/def_node.rb
194
182
  - lib/rubocop/ast/node/defined_node.rb
195
183
  - lib/rubocop/ast/node/ensure_node.rb
@@ -207,12 +195,14 @@ files:
207
195
  - lib/rubocop/ast/node/mixin/modifier_node.rb
208
196
  - lib/rubocop/ast/node/mixin/parameterized_node.rb
209
197
  - lib/rubocop/ast/node/mixin/predicate_operator_node.rb
198
+ - lib/rubocop/ast/node/module_node.rb
210
199
  - lib/rubocop/ast/node/or_node.rb
211
200
  - lib/rubocop/ast/node/pair_node.rb
212
201
  - lib/rubocop/ast/node/range_node.rb
213
202
  - lib/rubocop/ast/node/regexp_node.rb
214
203
  - lib/rubocop/ast/node/resbody_node.rb
215
204
  - lib/rubocop/ast/node/retry_node.rb
205
+ - lib/rubocop/ast/node/self_class_node.rb
216
206
  - lib/rubocop/ast/node/send_node.rb
217
207
  - lib/rubocop/ast/node/str_node.rb
218
208
  - lib/rubocop/ast/node/super_node.rb
@@ -270,6 +260,7 @@ files:
270
260
  - lib/rubocop/cop/internal_affairs/redundant_message_argument.rb
271
261
  - lib/rubocop/cop/internal_affairs/useless_message_assertion.rb
272
262
  - lib/rubocop/cop/layout/access_modifier_indentation.rb
263
+ - lib/rubocop/cop/layout/align_arguments.rb
273
264
  - lib/rubocop/cop/layout/align_array.rb
274
265
  - lib/rubocop/cop/layout/align_hash.rb
275
266
  - lib/rubocop/cop/layout/align_parameters.rb
@@ -304,10 +295,12 @@ files:
304
295
  - lib/rubocop/cop/layout/first_hash_element_line_break.rb
305
296
  - lib/rubocop/cop/layout/first_method_argument_line_break.rb
306
297
  - lib/rubocop/cop/layout/first_method_parameter_line_break.rb
307
- - lib/rubocop/cop/layout/first_parameter_indentation.rb
308
- - lib/rubocop/cop/layout/indent_array.rb
298
+ - lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb
309
299
  - lib/rubocop/cop/layout/indent_assignment.rb
310
- - lib/rubocop/cop/layout/indent_hash.rb
300
+ - lib/rubocop/cop/layout/indent_first_argument.rb
301
+ - lib/rubocop/cop/layout/indent_first_array_element.rb
302
+ - lib/rubocop/cop/layout/indent_first_hash_element.rb
303
+ - lib/rubocop/cop/layout/indent_first_parameter.rb
311
304
  - lib/rubocop/cop/layout/indent_heredoc.rb
312
305
  - lib/rubocop/cop/layout/indentation_consistency.rb
313
306
  - lib/rubocop/cop/layout/indentation_width.rb
@@ -379,6 +372,7 @@ files:
379
372
  - lib/rubocop/cop/lint/float_out_of_range.rb
380
373
  - lib/rubocop/cop/lint/format_parameter_mismatch.rb
381
374
  - lib/rubocop/cop/lint/handle_exceptions.rb
375
+ - lib/rubocop/cop/lint/heredoc_method_call_position.rb
382
376
  - lib/rubocop/cop/lint/implicit_string_concatenation.rb
383
377
  - lib/rubocop/cop/lint/ineffective_access_modifier.rb
384
378
  - lib/rubocop/cop/lint/inherit_exception.rb
@@ -446,10 +440,10 @@ files:
446
440
  - lib/rubocop/cop/metrics/utils/abc_size_calculator.rb
447
441
  - lib/rubocop/cop/mixin/alignment.rb
448
442
  - lib/rubocop/cop/mixin/annotation_comment.rb
449
- - lib/rubocop/cop/mixin/array_hash_indentation.rb
450
443
  - lib/rubocop/cop/mixin/array_min_size.rb
451
444
  - lib/rubocop/cop/mixin/array_syntax.rb
452
445
  - lib/rubocop/cop/mixin/check_assignment.rb
446
+ - lib/rubocop/cop/mixin/check_line_breakable.rb
453
447
  - lib/rubocop/cop/mixin/classish_length.rb
454
448
  - lib/rubocop/cop/mixin/code_length.rb
455
449
  - lib/rubocop/cop/mixin/configurable_enforced_style.rb
@@ -475,6 +469,7 @@ files:
475
469
  - lib/rubocop/cop/mixin/method_complexity.rb
476
470
  - lib/rubocop/cop/mixin/method_preference.rb
477
471
  - lib/rubocop/cop/mixin/min_body_length.rb
472
+ - lib/rubocop/cop/mixin/multiline_element_indentation.rb
478
473
  - lib/rubocop/cop/mixin/multiline_element_line_breaks.rb
479
474
  - lib/rubocop/cop/mixin/multiline_expression_indentation.rb
480
475
  - lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb
@@ -522,31 +517,6 @@ files:
522
517
  - lib/rubocop/cop/naming/variable_name.rb
523
518
  - lib/rubocop/cop/naming/variable_number.rb
524
519
  - lib/rubocop/cop/offense.rb
525
- - lib/rubocop/cop/performance/caller.rb
526
- - lib/rubocop/cop/performance/case_when_splat.rb
527
- - lib/rubocop/cop/performance/casecmp.rb
528
- - lib/rubocop/cop/performance/chain_array_allocation.rb
529
- - lib/rubocop/cop/performance/compare_with_block.rb
530
- - lib/rubocop/cop/performance/count.rb
531
- - lib/rubocop/cop/performance/detect.rb
532
- - lib/rubocop/cop/performance/double_start_end_with.rb
533
- - lib/rubocop/cop/performance/end_with.rb
534
- - lib/rubocop/cop/performance/fixed_size.rb
535
- - lib/rubocop/cop/performance/flat_map.rb
536
- - lib/rubocop/cop/performance/inefficient_hash_search.rb
537
- - lib/rubocop/cop/performance/open_struct.rb
538
- - lib/rubocop/cop/performance/range_include.rb
539
- - lib/rubocop/cop/performance/redundant_block_call.rb
540
- - lib/rubocop/cop/performance/redundant_match.rb
541
- - lib/rubocop/cop/performance/redundant_merge.rb
542
- - lib/rubocop/cop/performance/regexp_match.rb
543
- - lib/rubocop/cop/performance/reverse_each.rb
544
- - lib/rubocop/cop/performance/size.rb
545
- - lib/rubocop/cop/performance/start_with.rb
546
- - lib/rubocop/cop/performance/string_replacement.rb
547
- - lib/rubocop/cop/performance/times_map.rb
548
- - lib/rubocop/cop/performance/unfreeze_string.rb
549
- - lib/rubocop/cop/performance/uri_default_parser.rb
550
520
  - lib/rubocop/cop/rails/action_filter.rb
551
521
  - lib/rubocop/cop/rails/active_record_aliases.rb
552
522
  - lib/rubocop/cop/rails/active_record_override.rb
@@ -841,15 +811,21 @@ post_install_message: |
841
811
 
842
812
  Put this in your Gemfile.
843
813
 
844
- gem 'rubocop-performance'
814
+ ```rb
815
+ gem 'rubocop-performance'
816
+ ```
845
817
 
846
818
  And then execute:
847
819
 
848
- $ bundle install
820
+ ```sh
821
+ $ bundle install
822
+ ```
849
823
 
850
824
  Put this into your .rubocop.yml.
851
825
 
852
- require: rubocop-performance
826
+ ```yaml
827
+ require: rubocop-performance
828
+ ```
853
829
 
854
830
  More information: https://github.com/rubocop-hq/rubocop-performance
855
831
  rdoc_options: []
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # This cop identifies places where `caller[n]`
7
- # can be replaced by `caller(n..n).first`.
8
- #
9
- # @example
10
- # # bad
11
- # caller[1]
12
- # caller.first
13
- # caller_locations[1]
14
- # caller_locations.first
15
- #
16
- # # good
17
- # caller(2..2).first
18
- # caller(1..1).first
19
- # caller_locations(2..2).first
20
- # caller_locations(1..1).first
21
- class Caller < Cop
22
- MSG_BRACE = 'Use `%<method>s(%<n>d..%<n>d).first`' \
23
- ' instead of `%<method>s[%<m>d]`.'.freeze
24
- MSG_FIRST = 'Use `%<method>s(%<n>d..%<n>d).first`' \
25
- ' instead of `%<method>s.first`.'.freeze
26
-
27
- def_node_matcher :slow_caller?, <<-PATTERN
28
- {
29
- (send nil? {:caller :caller_locations})
30
- (send nil? {:caller :caller_locations} int)
31
- }
32
- PATTERN
33
-
34
- def_node_matcher :caller_with_scope_method?, <<-PATTERN
35
- {
36
- (send #slow_caller? :first)
37
- (send #slow_caller? :[] int)
38
- }
39
- PATTERN
40
-
41
- def on_send(node)
42
- return unless caller_with_scope_method?(node)
43
-
44
- add_offense(node)
45
- end
46
-
47
- private
48
-
49
- def message(node)
50
- method_name = node.receiver.method_name
51
- caller_arg = node.receiver.first_argument
52
- n = caller_arg ? int_value(caller_arg) : 1
53
-
54
- if node.method_name == :[]
55
- m = int_value(node.first_argument)
56
- n += m
57
- format(MSG_BRACE, n: n, m: m, method: method_name)
58
- else
59
- format(MSG_FIRST, n: n, method: method_name)
60
- end
61
- end
62
-
63
- def int_value(node)
64
- node.children[0]
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,177 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module Performance
6
- # Reordering `when` conditions with a splat to the end
7
- # of the `when` branches can improve performance.
8
- #
9
- # Ruby has to allocate memory for the splat expansion every time
10
- # that the `case` `when` statement is run. Since Ruby does not support
11
- # fall through inside of `case` `when`, like some other languages do,
12
- # the order of the `when` branches should not matter. By placing any
13
- # splat expansions at the end of the list of `when` branches we will
14
- # reduce the number of times that memory has to be allocated for
15
- # the expansion. The exception to this is if multiple of your `when`
16
- # conditions can be true for any given condition. A likely scenario for
17
- # this defining a higher level when condition to override a condition
18
- # that is inside of the splat expansion.
19
- #
20
- # This is not a guaranteed performance improvement. If the data being
21
- # processed by the `case` condition is normalized in a manner that favors
22
- # hitting a condition in the splat expansion, it is possible that
23
- # moving the splat condition to the end will use more memory,
24
- # and run slightly slower.
25
- #
26
- # @example
27
- # # bad
28
- # case foo
29
- # when *condition
30
- # bar
31
- # when baz
32
- # foobar
33
- # end
34
- #
35
- # case foo
36
- # when *[1, 2, 3, 4]
37
- # bar
38
- # when 5
39
- # baz
40
- # end
41
- #
42
- # # good
43
- # case foo
44
- # when baz
45
- # foobar
46
- # when *condition
47
- # bar
48
- # end
49
- #
50
- # case foo
51
- # when 1, 2, 3, 4
52
- # bar
53
- # when 5
54
- # baz
55
- # end
56
- class CaseWhenSplat < Cop
57
- include Alignment
58
- include RangeHelp
59
-
60
- MSG = 'Reordering `when` conditions with a splat to the end ' \
61
- 'of the `when` branches can improve performance.'.freeze
62
- ARRAY_MSG = 'Pass the contents of array literals ' \
63
- 'directly to `when` conditions.'.freeze
64
-
65
- def on_case(case_node)
66
- when_conditions = case_node.when_branches.flat_map(&:conditions)
67
-
68
- splat_offenses(when_conditions).reverse_each do |condition|
69
- range = condition.parent.loc.keyword.join(condition.source_range)
70
- variable, = *condition
71
- message = variable.array_type? ? ARRAY_MSG : MSG
72
- add_offense(condition.parent, location: range, message: message)
73
- end
74
- end
75
-
76
- def autocorrect(when_node)
77
- lambda do |corrector|
78
- if needs_reorder?(when_node)
79
- reorder_condition(corrector, when_node)
80
- else
81
- inline_fix_branch(corrector, when_node)
82
- end
83
- end
84
- end
85
-
86
- private
87
-
88
- def replacement(conditions)
89
- reordered = conditions.partition(&:splat_type?).reverse
90
- reordered.flatten.map(&:source).join(', ')
91
- end
92
-
93
- def inline_fix_branch(corrector, when_node)
94
- conditions = when_node.conditions
95
- range = range_between(conditions[0].loc.expression.begin_pos,
96
- conditions[-1].loc.expression.end_pos)
97
-
98
- corrector.replace(range, replacement(conditions))
99
- end
100
-
101
- def reorder_condition(corrector, when_node)
102
- when_branches = when_node.parent.when_branches
103
-
104
- return if when_branches.one?
105
-
106
- corrector.remove(when_branch_range(when_node))
107
- corrector.insert_after(when_branches.last.source_range,
108
- reordering_correction(when_node))
109
- end
110
-
111
- def reordering_correction(when_node)
112
- new_condition = replacement(when_node.conditions)
113
-
114
- if same_line?(when_node, when_node.body)
115
- new_condition_with_then(when_node, new_condition)
116
- else
117
- new_branch_without_then(when_node, new_condition)
118
- end
119
- end
120
-
121
- def when_branch_range(when_node)
122
- next_branch =
123
- when_node.parent.when_branches[when_node.branch_index + 1]
124
-
125
- range_between(when_node.source_range.begin_pos,
126
- next_branch.source_range.begin_pos)
127
- end
128
-
129
- def new_condition_with_then(node, new_condition)
130
- "\n#{indent_for(node)}when " \
131
- "#{new_condition} then #{node.body.source}"
132
- end
133
-
134
- def new_branch_without_then(node, new_condition)
135
- "\n#{indent_for(node)}when #{new_condition}" \
136
- "\n#{indent_for(node.body)}#{node.body.source}"
137
- end
138
-
139
- def indent_for(node)
140
- ' ' * node.loc.column
141
- end
142
-
143
- def splat_offenses(when_conditions)
144
- found_non_splat = false
145
-
146
- offenses = when_conditions.reverse.map do |condition|
147
- found_non_splat ||= non_splat?(condition)
148
-
149
- next if non_splat?(condition)
150
-
151
- condition if found_non_splat
152
- end
153
-
154
- offenses.compact
155
- end
156
-
157
- def non_splat?(condition)
158
- variable, = *condition
159
-
160
- (condition.splat_type? && variable.array_type?) ||
161
- !condition.splat_type?
162
- end
163
-
164
- def needs_reorder?(when_node)
165
- following_branches =
166
- when_node.parent.when_branches[(when_node.branch_index + 1)..-1]
167
-
168
- following_branches.any? do |when_branch|
169
- when_branch.conditions.any? do |condition|
170
- non_splat?(condition)
171
- end
172
- end
173
- end
174
- end
175
- end
176
- end
177
- end