From 548a211d912487d4b90f5c5d130c909a709f5225 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 18 Nov 2021 11:22:19 +0900 Subject: [PATCH] Fix an incorrect autocorrect for `Performance/RedundantStringChars` Follow up to https://github.com/rubocop/rubocop-performance/issues/249#issuecomment-972262774. This PR fixes an incorrect autocorrect for `Performance/RedundantStringChars` when using `str.chars[0]`. --- ..._for_performance_redundant_string_chars.md | 1 + .../cop/performance/redundant_string_chars.rb | 22 +++++++++++++------ .../redundant_string_chars_spec.rb | 22 +++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 changelog/fix_incorrect_autocorrect_for_performance_redundant_string_chars.md diff --git a/changelog/fix_incorrect_autocorrect_for_performance_redundant_string_chars.md b/changelog/fix_incorrect_autocorrect_for_performance_redundant_string_chars.md new file mode 100644 index 0000000000..f29d3ab6eb --- /dev/null +++ b/changelog/fix_incorrect_autocorrect_for_performance_redundant_string_chars.md @@ -0,0 +1 @@ +* [#273](https://github.com/rubocop/rubocop-performance/pull/273): Fix an incorrect autocorrect for `Performance/RedundantStringChars` when using `str.chars[0]`. ([@koic][]) diff --git a/lib/rubocop/cop/performance/redundant_string_chars.rb b/lib/rubocop/cop/performance/redundant_string_chars.rb index 20d9bc0c0c..d0d4972881 100644 --- a/lib/rubocop/cop/performance/redundant_string_chars.rb +++ b/lib/rubocop/cop/performance/redundant_string_chars.rb @@ -82,14 +82,10 @@ def build_message(method, args) def build_good_method(method, args) case method - when :[], :slice + when :slice "[#{build_call_args(args)}].chars" - when :first - if args.any? - "[0...#{args.first.source}].chars" - else - '[0]' - end + when :[], :first + build_good_method_for_brackets_or_first_method(method, args) when :take "[0...#{args.first.source}].chars" else @@ -97,6 +93,18 @@ def build_good_method(method, args) end end + def build_good_method_for_brackets_or_first_method(method, args) + first_arg = args.first + + if first_arg&.range_type? + "[#{build_call_args(args)}].chars" + elsif method == :first && args.any? + "[0...#{args.first.source}].chars" + else + first_arg ? "[#{first_arg.source}]" : '[0]' + end + end + def build_bad_method(method, args) case method when :[] diff --git a/spec/rubocop/cop/performance/redundant_string_chars_spec.rb b/spec/rubocop/cop/performance/redundant_string_chars_spec.rb index df256631fe..a5208110f5 100644 --- a/spec/rubocop/cop/performance/redundant_string_chars_spec.rb +++ b/spec/rubocop/cop/performance/redundant_string_chars_spec.rb @@ -34,6 +34,28 @@ RUBY end + it 'registers an offense and corrects when using `str.chars[0]`' do + expect_offense(<<~RUBY) + str.chars[0] + ^^^^^^^^ Use `[0]` instead of `chars[0]`. + RUBY + + expect_correction(<<~RUBY) + str[0] + RUBY + end + + it 'registers an offense and corrects when using `str.chars[42]`' do + expect_offense(<<~RUBY) + str.chars[42] + ^^^^^^^^^ Use `[42]` instead of `chars[42]`. + RUBY + + expect_correction(<<~RUBY) + str[42] + RUBY + end + it 'registers an offense and corrects when using `str.chars.first(2)`' do expect_offense(<<~RUBY) str.chars.first(2)