rubocop-performance 1.24.0 → 1.25.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b4cdc2536f76691be677a1e203a886fae5e170f550424bed14d579f39a87e75
4
- data.tar.gz: 6ea02935a50fcdeb0b07d1a5d67c4414c71115019cb02dae4746c207f798cad6
3
+ metadata.gz: c195b128694fb4d65674a0d361a04e6db9c10671a2d04c59f714b92abf7a7192
4
+ data.tar.gz: 4e487319e1b81dc1f9aa515960f2b0546cfdf73483f8baac14de35049086a97a
5
5
  SHA512:
6
- metadata.gz: 7bc4f69ef0a5ca779626b29d0a7c5333bf135b29d06d1be009acd4e9ffaa368873cb9977a94e9c5d5f50cb1c000d9fa243b8557badbab00756469a0b6a366662
7
- data.tar.gz: 47e7f03cf61d57a3f9bd8e3cdb79f722fdaa279d300d2de5532435c1231fa06c28b1a148ab31c7b62775d1449a284fc43cee4bd36bbd16b1065145f022c8f729
6
+ metadata.gz: db0f96d9a383aca44da3760e9a22a54aaa17d59f6e24fb4de891954120f57ce38487fae8ce3436f0082d49b414f1c3e2aeea63bf5802e6bff43eea42760a11d9
7
+ data.tar.gz: 2e351cffc40a87a928472c300a11bd6fe7e4959dbf30d94aadd2246c71e9ab873bcf54971201fe62c2824c2982c381810ea0d8c9e228f09d0f0dbd0ed3cd8e2f
@@ -12,6 +12,14 @@ module RuboCop
12
12
  # You can set the minimum number of elements to consider
13
13
  # an offense with `MinSize`.
14
14
  #
15
+ # NOTE: Since Ruby 3.4, certain simple arguments to `Array#include?` are
16
+ # optimized directly in Ruby. This avoids allocations without changing the
17
+ # code, as such no offense will be registered in those cases. Currently that
18
+ # includes: strings, `self`, local variables, instance variables, and method
19
+ # calls without arguments. Additionally, any number of methods can be chained:
20
+ # `[1, 2, 3].include?(@foo)` and `[1, 2, 3].include?(@foo.bar.baz)` both avoid
21
+ # the array allocation.
22
+ #
15
23
  # @example
16
24
  # # bad
17
25
  # users.select do |user|
@@ -55,6 +63,8 @@ module RuboCop
55
63
 
56
64
  ARRAY_METHODS = (ENUMERABLE_METHOD_NAMES | NONMUTATING_ARRAY_METHODS).to_set.freeze
57
65
 
66
+ ARRAY_INCLUDE_OPTIMIZED_TYPES = %i[str self lvar ivar send].freeze
67
+
58
68
  NONMUTATING_HASH_METHODS = %i[< <= == > >= [] any? assoc compact dig
59
69
  each each_key each_pair each_value empty?
60
70
  eql? fetch fetch_values filter flatten has_key?
@@ -80,8 +90,8 @@ module RuboCop
80
90
  PATTERN
81
91
 
82
92
  def on_send(node)
83
- receiver, method, = *node.children
84
- return unless check_literal?(receiver, method) && parent_is_loop?(receiver)
93
+ receiver, method, *arguments = *node.children
94
+ return unless check_literal?(receiver, method, arguments) && parent_is_loop?(receiver)
85
95
 
86
96
  message = format(MSG, literal_class: literal_class(receiver))
87
97
  add_offense(receiver, message: message)
@@ -89,12 +99,33 @@ module RuboCop
89
99
 
90
100
  private
91
101
 
92
- def check_literal?(node, method)
102
+ def check_literal?(node, method, arguments)
93
103
  !node.nil? &&
94
104
  nonmutable_method_of_array_or_hash?(node, method) &&
95
105
  node.children.size >= min_size &&
96
- node.recursive_basic_literal?
106
+ node.recursive_basic_literal? &&
107
+ !optimized_array_include?(node, method, arguments)
108
+ end
109
+
110
+ # Since Ruby 3.4, simple arguments to Array#include? are optimized.
111
+ # See https://github.com/ruby/ruby/pull/12123 for more details.
112
+ # rubocop:disable Metrics/CyclomaticComplexity
113
+ def optimized_array_include?(node, method, arguments)
114
+ return false unless target_ruby_version >= 3.4 && node.array_type? && method == :include?
115
+ # Disallow include?(1, 2)
116
+ return false if arguments.count != 1
117
+
118
+ arg = arguments.first
119
+ # Allow `include?(foo.bar.baz.bat)`
120
+ while arg.send_type?
121
+ return false if arg.arguments.any? # Disallow include?(foo(bar))
122
+ break unless arg.receiver
123
+
124
+ arg = arg.receiver
125
+ end
126
+ ARRAY_INCLUDE_OPTIMIZED_TYPES.include?(arg.type)
97
127
  end
128
+ # rubocop:enable Metrics/CyclomaticComplexity
98
129
 
99
130
  def nonmutable_method_of_array_or_hash?(node, method)
100
131
  (node.array_type? && ARRAY_METHODS.include?(method)) ||
@@ -75,7 +75,7 @@ module RuboCop
75
75
  end
76
76
 
77
77
  def allowed_parent?(node)
78
- node&.type?(:casgn, :block)
78
+ node&.type?(:casgn, :any_block)
79
79
  end
80
80
 
81
81
  def contains_splat?(node)
@@ -84,8 +84,7 @@ module RuboCop
84
84
  end
85
85
 
86
86
  def use_long_method
87
- preferred_config = config.for_all_cops['Style/PreferredHashMethods']
88
- preferred_config && preferred_config['EnforcedStyle'] == 'long' && preferred_config['Enabled']
87
+ config.for_enabled_cop('Style/PreferredHashMethods')['EnforcedStyle'] == 'long'
89
88
  end
90
89
 
91
90
  def correct_argument(node)
@@ -16,19 +16,19 @@ module RuboCop
16
16
  # send('do_something')
17
17
  # attr_accessor 'do_something'
18
18
  # instance_variable_get('@ivar')
19
- # respond_to?("string_#{interpolation}")
20
19
  #
21
20
  # # good
22
21
  # send(:do_something)
23
22
  # attr_accessor :do_something
24
23
  # instance_variable_get(:@ivar)
25
- # respond_to?(:"string_#{interpolation}")
26
24
  #
27
25
  # # good - these methods don't support namespaced symbols
28
26
  # const_get("#{module_path}::Base")
29
27
  # const_source_location("#{module_path}::Base")
30
28
  # const_defined?("#{module_path}::Base")
31
29
  #
30
+ # # good - using a symbol when string interpolation is involved causes a performance regression.
31
+ # respond_to?("string_#{interpolation}")
32
32
  #
33
33
  class StringIdentifierArgument < Base
34
34
  extend AutoCorrector
@@ -40,8 +40,6 @@ module RuboCop
40
40
  protected public public_constant module_function
41
41
  ].freeze
42
42
 
43
- INTERPOLATION_IGNORE_METHODS = %i[const_get const_source_location const_defined?].freeze
44
-
45
43
  TWO_ARGUMENTS_METHOD = :alias_method
46
44
  MULTIPLE_ARGUMENTS_METHODS = %i[
47
45
  attr_accessor attr_reader attr_writer private private_constant
@@ -59,7 +57,7 @@ module RuboCop
59
57
  deprecate_constant remove_const ruby2_keywords define_singleton_method instance_variable_defined?
60
58
  instance_variable_get instance_variable_set method public_method public_send remove_instance_variable
61
59
  respond_to? send singleton_method __send__
62
- ] + COMMAND_METHODS + INTERPOLATION_IGNORE_METHODS).freeze
60
+ ] + COMMAND_METHODS).freeze
63
61
 
64
62
  def on_send(node)
65
63
  return if COMMAND_METHODS.include?(node.method_name) && node.receiver
@@ -83,13 +81,7 @@ module RuboCop
83
81
  [node.first_argument]
84
82
  end
85
83
 
86
- arguments.compact.filter { |argument| string_argument_compatible?(argument, node) }
87
- end
88
-
89
- def string_argument_compatible?(argument, node)
90
- return true if argument.str_type?
91
-
92
- argument.dstr_type? && INTERPOLATION_IGNORE_METHODS.none? { |method| node.method?(method) }
84
+ arguments.compact.filter(&:str_type?)
93
85
  end
94
86
 
95
87
  def register_offense(argument, argument_value)
@@ -52,6 +52,7 @@ module RuboCop
52
52
  check(node)
53
53
  end
54
54
  alias on_numblock on_block
55
+ alias on_itblock on_block
55
56
 
56
57
  private
57
58
 
@@ -28,6 +28,7 @@ module RuboCop
28
28
  {
29
29
  (block (call !nil? RESTRICT_ON_SEND) (args (arg _)) (array (lvar _)))
30
30
  (numblock (call !nil? RESTRICT_ON_SEND) 1 (array (lvar _)))
31
+ (itblock (call !nil? RESTRICT_ON_SEND) :it (array (lvar _)))
31
32
  }
32
33
  PATTERN
33
34
 
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Performance
5
5
  # This module holds the RuboCop Performance version information.
6
6
  module Version
7
- STRING = '1.24.0'
7
+ STRING = '1.25.0'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.24.0
4
+ version: 1.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-02-15 00:00:00.000000000 Z
13
+ date: 2025-04-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: lint_roller
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirements:
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: 1.72.1
35
+ version: 1.75.0
36
36
  - - "<"
37
37
  - !ruby/object:Gem::Version
38
38
  version: '2.0'
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: 1.72.1
45
+ version: 1.75.0
46
46
  - - "<"
47
47
  - !ruby/object:Gem::Version
48
48
  version: '2.0'
@@ -146,7 +146,7 @@ metadata:
146
146
  homepage_uri: https://docs.rubocop.org/rubocop-performance/
147
147
  changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
148
148
  source_code_uri: https://github.com/rubocop/rubocop-performance/
149
- documentation_uri: https://docs.rubocop.org/rubocop-performance/1.24/
149
+ documentation_uri: https://docs.rubocop.org/rubocop-performance/1.25/
150
150
  bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
151
151
  rubygems_mfa_required: 'true'
152
152
  default_lint_roller_plugin: RuboCop::Performance::Plugin