rubocop 0.67.2 → 0.68.0

Sign up to get free protection for your applications and to get access to all the features.
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