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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +86 -233
- data/exe/rubocop +0 -12
- data/lib/rubocop.rb +13 -30
- data/lib/rubocop/ast/builder.rb +4 -0
- data/lib/rubocop/ast/node/alias_node.rb +24 -0
- data/lib/rubocop/ast/node/class_node.rb +31 -0
- data/lib/rubocop/ast/node/module_node.rb +24 -0
- data/lib/rubocop/ast/node/range_node.rb +7 -0
- data/lib/rubocop/ast/node/resbody_node.rb +12 -0
- data/lib/rubocop/ast/node/self_class_node.rb +24 -0
- data/lib/rubocop/cli.rb +40 -4
- data/lib/rubocop/config.rb +9 -7
- data/lib/rubocop/config_loader.rb +48 -7
- data/lib/rubocop/config_loader_resolver.rb +5 -4
- data/lib/rubocop/cop/commissioner.rb +24 -0
- data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +18 -6
- data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +12 -14
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +9 -20
- data/lib/rubocop/cop/layout/align_arguments.rb +93 -0
- data/lib/rubocop/cop/layout/align_parameters.rb +57 -33
- data/lib/rubocop/cop/layout/class_structure.rb +5 -5
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +6 -8
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +3 -6
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +1 -2
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -0
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +292 -0
- data/lib/rubocop/cop/layout/{first_parameter_indentation.rb → indent_first_argument.rb} +11 -12
- data/lib/rubocop/cop/layout/{indent_array.rb → indent_first_array_element.rb} +2 -2
- data/lib/rubocop/cop/layout/{indent_hash.rb → indent_first_hash_element.rb} +2 -2
- data/lib/rubocop/cop/layout/indent_first_parameter.rb +96 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +4 -16
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -4
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -16
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +6 -8
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -8
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +157 -0
- data/lib/rubocop/cop/lint/inherit_exception.rb +3 -4
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +18 -1
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -5
- data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +25 -5
- data/lib/rubocop/cop/lint/useless_assignment.rb +2 -6
- data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -2
- data/lib/rubocop/cop/message_annotator.rb +1 -0
- data/lib/rubocop/cop/metrics/line_length.rb +139 -28
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +3 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +190 -0
- data/lib/rubocop/cop/mixin/{array_hash_indentation.rb → multiline_element_indentation.rb} +3 -2
- data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -7
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +33 -4
- data/lib/rubocop/cop/rails/active_record_override.rb +23 -8
- data/lib/rubocop/cop/rails/delegate.rb +5 -8
- data/lib/rubocop/cop/rails/environment_comparison.rb +5 -3
- data/lib/rubocop/cop/rails/find_each.rb +1 -1
- data/lib/rubocop/cop/rails/redundant_allow_nil.rb +3 -3
- data/lib/rubocop/cop/rails/reflection_class_name.rb +1 -1
- data/lib/rubocop/cop/rails/skips_model_validations.rb +6 -7
- data/lib/rubocop/cop/rails/time_zone.rb +3 -10
- data/lib/rubocop/cop/rails/validation.rb +3 -0
- data/lib/rubocop/cop/registry.rb +3 -3
- data/lib/rubocop/cop/style/alias.rb +13 -7
- data/lib/rubocop/cop/style/block_delimiters.rb +20 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +19 -21
- data/lib/rubocop/cop/style/class_methods.rb +16 -24
- data/lib/rubocop/cop/style/conditional_assignment.rb +20 -49
- data/lib/rubocop/cop/style/documentation.rb +3 -7
- data/lib/rubocop/cop/style/format_string.rb +18 -21
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +4 -0
- data/lib/rubocop/cop/style/lambda.rb +12 -8
- data/lib/rubocop/cop/style/mixin_grouping.rb +8 -10
- data/lib/rubocop/cop/style/module_function.rb +2 -3
- data/lib/rubocop/cop/style/next.rb +10 -14
- data/lib/rubocop/cop/style/one_line_conditional.rb +5 -3
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -4
- data/lib/rubocop/cop/style/random_with_offset.rb +44 -47
- data/lib/rubocop/cop/style/redundant_return.rb +6 -14
- data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +3 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +2 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +20 -40
- data/lib/rubocop/cop/style/unless_else.rb +1 -2
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -7
- data/lib/rubocop/cop/util.rb +2 -4
- data/lib/rubocop/file_finder.rb +5 -10
- data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -0
- data/lib/rubocop/node_pattern.rb +304 -170
- data/lib/rubocop/options.rb +4 -1
- data/lib/rubocop/rspec/shared_contexts.rb +3 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +1 -1
- metadata +26 -50
- data/lib/rubocop/cop/performance/caller.rb +0 -69
- data/lib/rubocop/cop/performance/case_when_splat.rb +0 -177
- data/lib/rubocop/cop/performance/casecmp.rb +0 -108
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +0 -78
- data/lib/rubocop/cop/performance/compare_with_block.rb +0 -122
- data/lib/rubocop/cop/performance/count.rb +0 -102
- data/lib/rubocop/cop/performance/detect.rb +0 -110
- data/lib/rubocop/cop/performance/double_start_end_with.rb +0 -94
- data/lib/rubocop/cop/performance/end_with.rb +0 -56
- data/lib/rubocop/cop/performance/fixed_size.rb +0 -97
- data/lib/rubocop/cop/performance/flat_map.rb +0 -78
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +0 -99
- data/lib/rubocop/cop/performance/open_struct.rb +0 -46
- data/lib/rubocop/cop/performance/range_include.rb +0 -50
- data/lib/rubocop/cop/performance/redundant_block_call.rb +0 -93
- data/lib/rubocop/cop/performance/redundant_match.rb +0 -56
- data/lib/rubocop/cop/performance/redundant_merge.rb +0 -183
- data/lib/rubocop/cop/performance/regexp_match.rb +0 -265
- data/lib/rubocop/cop/performance/reverse_each.rb +0 -42
- data/lib/rubocop/cop/performance/size.rb +0 -77
- data/lib/rubocop/cop/performance/start_with.rb +0 -59
- data/lib/rubocop/cop/performance/string_replacement.rb +0 -173
- data/lib/rubocop/cop/performance/times_map.rb +0 -71
- data/lib/rubocop/cop/performance/unfreeze_string.rb +0 -50
- data/lib/rubocop/cop/performance/uri_default_parser.rb +0 -47
data/lib/rubocop/options.rb
CHANGED
@@ -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
|
data/lib/rubocop/version.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# This module holds the RuboCop version information.
|
5
5
|
module Version
|
6
|
-
STRING = '0.
|
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
|
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.
|
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-
|
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.
|
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.
|
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/
|
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/
|
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
|
-
|
814
|
+
```rb
|
815
|
+
gem 'rubocop-performance'
|
816
|
+
```
|
845
817
|
|
846
818
|
And then execute:
|
847
819
|
|
848
|
-
|
820
|
+
```sh
|
821
|
+
$ bundle install
|
822
|
+
```
|
849
823
|
|
850
824
|
Put this into your .rubocop.yml.
|
851
825
|
|
852
|
-
|
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
|