activesupport 6.0.0.beta2 → 6.0.2.rc1
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.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +287 -3
- data/README.rdoc +2 -1
- data/lib/active_support.rb +1 -0
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +5 -1
- data/lib/active_support/cache.rb +5 -5
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/redis_cache_store.rb +9 -6
- data/lib/active_support/concern.rb +24 -1
- data/lib/active_support/configurable.rb +3 -3
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/class/attribute.rb +10 -15
- data/lib/active_support/core_ext/date_and_time/calculations.rb +0 -30
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +24 -4
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +2 -2
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +5 -5
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +5 -5
- data/lib/active_support/core_ext/module/delegation.rb +6 -0
- data/lib/active_support/core_ext/object/duplicable.rb +7 -117
- data/lib/active_support/core_ext/range/compare_range.rb +27 -12
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/output_safety.rb +51 -4
- data/lib/active_support/core_ext/time/calculations.rb +31 -2
- data/lib/active_support/dependencies.rb +41 -5
- data/lib/active_support/dependencies/zeitwerk_integration.rb +44 -21
- data/lib/active_support/deprecation/method_wrappers.rb +7 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +24 -3
- data/lib/active_support/descendants_tracker.rb +52 -6
- data/lib/active_support/duration.rb +2 -3
- data/lib/active_support/evented_file_update_checker.rb +14 -2
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/hash_with_indifferent_access.rb +6 -3
- data/lib/active_support/i18n_railtie.rb +6 -1
- data/lib/active_support/inflector/transliterate.rb +43 -14
- data/lib/active_support/logger_thread_safe_level.rb +2 -1
- data/lib/active_support/notifications/fanout.rb +2 -2
- data/lib/active_support/notifications/instrumenter.rb +12 -11
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +6 -1
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/subscriber.rb +55 -6
- data/lib/active_support/testing/parallelization.rb +21 -2
- metadata +13 -14
| @@ -3,54 +3,69 @@ | |
| 3 3 | 
             
            module ActiveSupport
         | 
| 4 4 | 
             
              module CompareWithRange
         | 
| 5 5 | 
             
                # Extends the default Range#=== to support range comparisons.
         | 
| 6 | 
            -
                #  (1..5) === (1..5) | 
| 7 | 
            -
                #  (1..5) === (2..3) | 
| 8 | 
            -
                #  (1..5) === ( | 
| 6 | 
            +
                #  (1..5) === (1..5)  # => true
         | 
| 7 | 
            +
                #  (1..5) === (2..3)  # => true
         | 
| 8 | 
            +
                #  (1..5) === (1...6) # => true
         | 
| 9 | 
            +
                #  (1..5) === (2..6)  # => false
         | 
| 9 10 | 
             
                #
         | 
| 10 11 | 
             
                # The native Range#=== behavior is untouched.
         | 
| 11 12 | 
             
                #  ('a'..'f') === ('c') # => true
         | 
| 12 13 | 
             
                #  (5..9) === (11) # => false
         | 
| 14 | 
            +
                #
         | 
| 15 | 
            +
                # The given range must be fully bounded, with both start and end.
         | 
| 13 16 | 
             
                def ===(value)
         | 
| 14 17 | 
             
                  if value.is_a?(::Range)
         | 
| 15 18 | 
             
                    # 1...10 includes 1..9 but it does not include 1..10.
         | 
| 19 | 
            +
                    # 1..10 includes 1...11 but it does not include 1...12.
         | 
| 16 20 | 
             
                    operator = exclude_end? && !value.exclude_end? ? :< : :<=
         | 
| 17 | 
            -
                     | 
| 21 | 
            +
                    value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
         | 
| 22 | 
            +
                    super(value.first) && (self.end.nil? || value_max.send(operator, last))
         | 
| 18 23 | 
             
                  else
         | 
| 19 24 | 
             
                    super
         | 
| 20 25 | 
             
                  end
         | 
| 21 26 | 
             
                end
         | 
| 22 27 |  | 
| 23 28 | 
             
                # Extends the default Range#include? to support range comparisons.
         | 
| 24 | 
            -
                #  (1..5).include?(1..5) | 
| 25 | 
            -
                #  (1..5).include?(2..3) | 
| 26 | 
            -
                #  (1..5).include?( | 
| 29 | 
            +
                #  (1..5).include?(1..5)  # => true
         | 
| 30 | 
            +
                #  (1..5).include?(2..3)  # => true
         | 
| 31 | 
            +
                #  (1..5).include?(1...6) # => true
         | 
| 32 | 
            +
                #  (1..5).include?(2..6)  # => false
         | 
| 27 33 | 
             
                #
         | 
| 28 34 | 
             
                # The native Range#include? behavior is untouched.
         | 
| 29 35 | 
             
                #  ('a'..'f').include?('c') # => true
         | 
| 30 36 | 
             
                #  (5..9).include?(11) # => false
         | 
| 37 | 
            +
                #
         | 
| 38 | 
            +
                # The given range must be fully bounded, with both start and end.
         | 
| 31 39 | 
             
                def include?(value)
         | 
| 32 40 | 
             
                  if value.is_a?(::Range)
         | 
| 33 41 | 
             
                    # 1...10 includes 1..9 but it does not include 1..10.
         | 
| 42 | 
            +
                    # 1..10 includes 1...11 but it does not include 1...12.
         | 
| 34 43 | 
             
                    operator = exclude_end? && !value.exclude_end? ? :< : :<=
         | 
| 35 | 
            -
                     | 
| 44 | 
            +
                    value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
         | 
| 45 | 
            +
                    super(value.first) && (self.end.nil? || value_max.send(operator, last))
         | 
| 36 46 | 
             
                  else
         | 
| 37 47 | 
             
                    super
         | 
| 38 48 | 
             
                  end
         | 
| 39 49 | 
             
                end
         | 
| 40 50 |  | 
| 41 51 | 
             
                # Extends the default Range#cover? to support range comparisons.
         | 
| 42 | 
            -
                #  (1..5).cover?(1..5) | 
| 43 | 
            -
                #  (1..5).cover?(2..3) | 
| 44 | 
            -
                #  (1..5).cover?( | 
| 52 | 
            +
                #  (1..5).cover?(1..5)  # => true
         | 
| 53 | 
            +
                #  (1..5).cover?(2..3)  # => true
         | 
| 54 | 
            +
                #  (1..5).cover?(1...6) # => true
         | 
| 55 | 
            +
                #  (1..5).cover?(2..6)  # => false
         | 
| 45 56 | 
             
                #
         | 
| 46 57 | 
             
                # The native Range#cover? behavior is untouched.
         | 
| 47 58 | 
             
                #  ('a'..'f').cover?('c') # => true
         | 
| 48 59 | 
             
                #  (5..9).cover?(11) # => false
         | 
| 60 | 
            +
                #
         | 
| 61 | 
            +
                # The given range must be fully bounded, with both start and end.
         | 
| 49 62 | 
             
                def cover?(value)
         | 
| 50 63 | 
             
                  if value.is_a?(::Range)
         | 
| 51 64 | 
             
                    # 1...10 covers 1..9 but it does not cover 1..10.
         | 
| 65 | 
            +
                    # 1..10 covers 1...11 but it does not cover 1...12.
         | 
| 52 66 | 
             
                    operator = exclude_end? && !value.exclude_end? ? :< : :<=
         | 
| 53 | 
            -
                     | 
| 67 | 
            +
                    value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
         | 
| 68 | 
            +
                    super(value.first) && (self.end.nil? || value_max.send(operator, last))
         | 
| 54 69 | 
             
                  else
         | 
| 55 70 | 
             
                    super
         | 
| 56 71 | 
             
                  end
         | 
| @@ -9,9 +9,9 @@ module ActiveSupport | |
| 9 9 | 
             
                #   (1.hour.ago..1.hour.from_now).include?(Time.current) # => true
         | 
| 10 10 | 
             
                #
         | 
| 11 11 | 
             
                def include?(value)
         | 
| 12 | 
            -
                  if  | 
| 12 | 
            +
                  if self.begin.is_a?(TimeWithZone)
         | 
| 13 13 | 
             
                    cover?(value)
         | 
| 14 | 
            -
                  elsif  | 
| 14 | 
            +
                  elsif self.end.is_a?(TimeWithZone)
         | 
| 15 15 | 
             
                    cover?(value)
         | 
| 16 16 | 
             
                  else
         | 
| 17 17 | 
             
                    super
         | 
| @@ -162,6 +162,11 @@ class String | |
| 162 162 |  | 
| 163 163 | 
             
              # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
         | 
| 164 164 | 
             
              #
         | 
| 165 | 
            +
              # If the optional parameter +locale+ is specified,
         | 
| 166 | 
            +
              # the word will be parameterized as a word of that language.
         | 
| 167 | 
            +
              # By default, this parameter is set to <tt>nil</tt> and it will use
         | 
| 168 | 
            +
              # the configured <tt>I18n.locale</tt>.
         | 
| 169 | 
            +
              #
         | 
| 165 170 | 
             
              #   class Person
         | 
| 166 171 | 
             
              #     def to_param
         | 
| 167 172 | 
             
              #       "#{id}-#{name.parameterize}"
         | 
| @@ -187,8 +192,8 @@ class String | |
| 187 192 | 
             
              #
         | 
| 188 193 | 
             
              #   <%= link_to(@person.name, person_path) %>
         | 
| 189 194 | 
             
              #   # => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
         | 
| 190 | 
            -
              def parameterize(separator: "-", preserve_case: false)
         | 
| 191 | 
            -
                ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case)
         | 
| 195 | 
            +
              def parameterize(separator: "-", preserve_case: false, locale: nil)
         | 
| 196 | 
            +
                ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case, locale: locale)
         | 
| 192 197 | 
             
              end
         | 
| 193 198 |  | 
| 194 199 | 
             
              # Creates the name of a table like Rails does for models to table names. This method
         | 
| @@ -135,10 +135,12 @@ module ActiveSupport #:nodoc: | |
| 135 135 | 
             
              class SafeBuffer < String
         | 
| 136 136 | 
             
                UNSAFE_STRING_METHODS = %w(
         | 
| 137 137 | 
             
                  capitalize chomp chop delete delete_prefix delete_suffix
         | 
| 138 | 
            -
                  downcase  | 
| 139 | 
            -
                   | 
| 138 | 
            +
                  downcase lstrip next reverse rstrip slice squeeze strip
         | 
| 139 | 
            +
                  succ swapcase tr tr_s unicode_normalize upcase
         | 
| 140 140 | 
             
                )
         | 
| 141 141 |  | 
| 142 | 
            +
                UNSAFE_STRING_METHODS_WITH_BACKREF = %w(gsub sub)
         | 
| 143 | 
            +
             | 
| 142 144 | 
             
                alias_method :original_concat, :concat
         | 
| 143 145 | 
             
                private :original_concat
         | 
| 144 146 |  | 
| @@ -199,14 +201,24 @@ module ActiveSupport #:nodoc: | |
| 199 201 | 
             
                  super(html_escape_interpolated_argument(value))
         | 
| 200 202 | 
             
                end
         | 
| 201 203 |  | 
| 202 | 
            -
                def []=( | 
| 203 | 
            -
                   | 
| 204 | 
            +
                def []=(*args)
         | 
| 205 | 
            +
                  if args.count == 3
         | 
| 206 | 
            +
                    super(args[0], args[1], html_escape_interpolated_argument(args[2]))
         | 
| 207 | 
            +
                  else
         | 
| 208 | 
            +
                    super(args[0], html_escape_interpolated_argument(args[1]))
         | 
| 209 | 
            +
                  end
         | 
| 204 210 | 
             
                end
         | 
| 205 211 |  | 
| 206 212 | 
             
                def +(other)
         | 
| 207 213 | 
             
                  dup.concat(other)
         | 
| 208 214 | 
             
                end
         | 
| 209 215 |  | 
| 216 | 
            +
                def *(*)
         | 
| 217 | 
            +
                  new_safe_buffer = super
         | 
| 218 | 
            +
                  new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
         | 
| 219 | 
            +
                  new_safe_buffer
         | 
| 220 | 
            +
                end
         | 
| 221 | 
            +
             | 
| 210 222 | 
             
                def %(args)
         | 
| 211 223 | 
             
                  case args
         | 
| 212 224 | 
             
                  when Hash
         | 
| @@ -249,11 +261,46 @@ module ActiveSupport #:nodoc: | |
| 249 261 | 
             
                  end
         | 
| 250 262 | 
             
                end
         | 
| 251 263 |  | 
| 264 | 
            +
                UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
         | 
| 265 | 
            +
                  if unsafe_method.respond_to?(unsafe_method)
         | 
| 266 | 
            +
                    class_eval <<-EOT, __FILE__, __LINE__ + 1
         | 
| 267 | 
            +
                      def #{unsafe_method}(*args, &block)             # def gsub(*args, &block)
         | 
| 268 | 
            +
                        if block                                      #   if block
         | 
| 269 | 
            +
                          to_str.#{unsafe_method}(*args) { |*params|  #     to_str.gsub(*args) { |*params|
         | 
| 270 | 
            +
                            set_block_back_references(block, $~)      #       set_block_back_references(block, $~)
         | 
| 271 | 
            +
                            block.call(*params)                       #       block.call(*params)
         | 
| 272 | 
            +
                          }                                           #     }
         | 
| 273 | 
            +
                        else                                          #   else
         | 
| 274 | 
            +
                          to_str.#{unsafe_method}(*args)              #     to_str.gsub(*args)
         | 
| 275 | 
            +
                        end                                           #   end
         | 
| 276 | 
            +
                      end                                             # end
         | 
| 277 | 
            +
             | 
| 278 | 
            +
                      def #{unsafe_method}!(*args, &block)            # def gsub!(*args, &block)
         | 
| 279 | 
            +
                        @html_safe = false                            #   @html_safe = false
         | 
| 280 | 
            +
                        if block                                      #   if block
         | 
| 281 | 
            +
                          super(*args) { |*params|                    #     super(*args) { |*params|
         | 
| 282 | 
            +
                            set_block_back_references(block, $~)      #       set_block_back_references(block, $~)
         | 
| 283 | 
            +
                            block.call(*params)                       #       block.call(*params)
         | 
| 284 | 
            +
                          }                                           #     }
         | 
| 285 | 
            +
                        else                                          #   else
         | 
| 286 | 
            +
                          super                                       #     super
         | 
| 287 | 
            +
                        end                                           #   end
         | 
| 288 | 
            +
                      end                                             # end
         | 
| 289 | 
            +
                    EOT
         | 
| 290 | 
            +
                  end
         | 
| 291 | 
            +
                end
         | 
| 292 | 
            +
             | 
| 252 293 | 
             
                private
         | 
| 253 294 |  | 
| 254 295 | 
             
                  def html_escape_interpolated_argument(arg)
         | 
| 255 296 | 
             
                    (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
         | 
| 256 297 | 
             
                  end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                  def set_block_back_references(block, match_data)
         | 
| 300 | 
            +
                    block.binding.eval("proc { |m| $~ = m }").call(match_data)
         | 
| 301 | 
            +
                  rescue ArgumentError
         | 
| 302 | 
            +
                    # Can't create binding from C level Proc
         | 
| 303 | 
            +
                  end
         | 
| 257 304 | 
             
              end
         | 
| 258 305 | 
             
            end
         | 
| 259 306 |  | 
| @@ -170,8 +170,7 @@ class Time | |
| 170 170 | 
             
                  options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
         | 
| 171 171 | 
             
                end
         | 
| 172 172 |  | 
| 173 | 
            -
                d = to_date.advance(options)
         | 
| 174 | 
            -
                d = d.gregorian if d.julian?
         | 
| 173 | 
            +
                d = to_date.gregorian.advance(options)
         | 
| 175 174 | 
             
                time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
         | 
| 176 175 | 
             
                seconds_to_advance = \
         | 
| 177 176 | 
             
                  options.fetch(:seconds, 0) +
         | 
| @@ -312,4 +311,34 @@ class Time | |
| 312 311 | 
             
              end
         | 
| 313 312 | 
             
              alias_method :eql_without_coercion, :eql?
         | 
| 314 313 | 
             
              alias_method :eql?, :eql_with_coercion
         | 
| 314 | 
            +
             | 
| 315 | 
            +
              # Returns a new time the specified number of days ago.
         | 
| 316 | 
            +
              def prev_day(days = 1)
         | 
| 317 | 
            +
                advance(days: -days)
         | 
| 318 | 
            +
              end
         | 
| 319 | 
            +
             | 
| 320 | 
            +
              # Returns a new time the specified number of days in the future.
         | 
| 321 | 
            +
              def next_day(days = 1)
         | 
| 322 | 
            +
                advance(days: days)
         | 
| 323 | 
            +
              end
         | 
| 324 | 
            +
             | 
| 325 | 
            +
              # Returns a new time the specified number of months ago.
         | 
| 326 | 
            +
              def prev_month(months = 1)
         | 
| 327 | 
            +
                advance(months: -months)
         | 
| 328 | 
            +
              end
         | 
| 329 | 
            +
             | 
| 330 | 
            +
              # Returns a new time the specified number of months in the future.
         | 
| 331 | 
            +
              def next_month(months = 1)
         | 
| 332 | 
            +
                advance(months: months)
         | 
| 333 | 
            +
              end
         | 
| 334 | 
            +
             | 
| 335 | 
            +
              # Returns a new time the specified number of years ago.
         | 
| 336 | 
            +
              def prev_year(years = 1)
         | 
| 337 | 
            +
                advance(years: -years)
         | 
| 338 | 
            +
              end
         | 
| 339 | 
            +
             | 
| 340 | 
            +
              # Returns a new time the specified number of years in the future.
         | 
| 341 | 
            +
              def next_year(years = 1)
         | 
| 342 | 
            +
                advance(years: years)
         | 
| 343 | 
            +
              end
         | 
| 315 344 | 
             
            end
         | 
| @@ -20,6 +20,9 @@ module ActiveSupport #:nodoc: | |
| 20 20 | 
             
              module Dependencies #:nodoc:
         | 
| 21 21 | 
             
                extend self
         | 
| 22 22 |  | 
| 23 | 
            +
                UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
         | 
| 24 | 
            +
                private_constant :UNBOUND_METHOD_MODULE_NAME
         | 
| 25 | 
            +
             | 
| 23 26 | 
             
                mattr_accessor :interlock, default: Interlock.new
         | 
| 24 27 |  | 
| 25 28 | 
             
                # :doc:
         | 
| @@ -70,6 +73,11 @@ module ActiveSupport #:nodoc: | |
| 70 73 | 
             
                # only once. All directories in this set must also be present in +autoload_paths+.
         | 
| 71 74 | 
             
                mattr_accessor :autoload_once_paths, default: []
         | 
| 72 75 |  | 
| 76 | 
            +
                # This is a private set that collects all eager load paths during bootstrap.
         | 
| 77 | 
            +
                # Useful for Zeitwerk integration. Its public interface is the config.* path
         | 
| 78 | 
            +
                # accessors of each engine.
         | 
| 79 | 
            +
                mattr_accessor :_eager_load_paths, default: Set.new
         | 
| 80 | 
            +
             | 
| 73 81 | 
             
                # An array of qualified constant names that have been loaded. Adding a name
         | 
| 74 82 | 
             
                # to this array will cause it to be unloaded the next time Dependencies are
         | 
| 75 83 | 
             
                # cleared.
         | 
| @@ -196,6 +204,11 @@ module ActiveSupport #:nodoc: | |
| 196 204 | 
             
                    end
         | 
| 197 205 | 
             
                  end
         | 
| 198 206 |  | 
| 207 | 
            +
                  def self.include_into(base)
         | 
| 208 | 
            +
                    base.include(self)
         | 
| 209 | 
            +
                    append_features(base)
         | 
| 210 | 
            +
                  end
         | 
| 211 | 
            +
             | 
| 199 212 | 
             
                  def const_missing(const_name)
         | 
| 200 213 | 
             
                    from_mod = anonymous? ? guess_for_anonymous(const_name) : self
         | 
| 201 214 | 
             
                    Dependencies.load_missing_constant(from_mod, const_name)
         | 
| @@ -225,6 +238,21 @@ module ActiveSupport #:nodoc: | |
| 225 238 | 
             
                    base.class_eval do
         | 
| 226 239 | 
             
                      define_method(:load, Kernel.instance_method(:load))
         | 
| 227 240 | 
             
                      private :load
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                      define_method(:require, Kernel.instance_method(:require))
         | 
| 243 | 
            +
                      private :require
         | 
| 244 | 
            +
                    end
         | 
| 245 | 
            +
                  end
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                  def self.include_into(base)
         | 
| 248 | 
            +
                    base.include(self)
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                    if base.instance_method(:load).owner == base
         | 
| 251 | 
            +
                      base.remove_method(:load)
         | 
| 252 | 
            +
                    end
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                    if base.instance_method(:require).owner == base
         | 
| 255 | 
            +
                      base.remove_method(:require)
         | 
| 228 256 | 
             
                    end
         | 
| 229 257 | 
             
                  end
         | 
| 230 258 |  | 
| @@ -321,9 +349,9 @@ module ActiveSupport #:nodoc: | |
| 321 349 | 
             
                end
         | 
| 322 350 |  | 
| 323 351 | 
             
                def hook!
         | 
| 324 | 
            -
                  Object | 
| 325 | 
            -
                  Module | 
| 326 | 
            -
                  Exception. | 
| 352 | 
            +
                  Loadable.include_into(Object)
         | 
| 353 | 
            +
                  ModuleConstMissing.include_into(Module)
         | 
| 354 | 
            +
                  Exception.include(Blamable)
         | 
| 327 355 | 
             
                end
         | 
| 328 356 |  | 
| 329 357 | 
             
                def unhook!
         | 
| @@ -634,7 +662,7 @@ module ActiveSupport #:nodoc: | |
| 634 662 |  | 
| 635 663 | 
             
                # Determine if the given constant has been automatically loaded.
         | 
| 636 664 | 
             
                def autoloaded?(desc)
         | 
| 637 | 
            -
                  return false if desc.is_a?(Module) && desc. | 
| 665 | 
            +
                  return false if desc.is_a?(Module) && real_mod_name(desc).nil?
         | 
| 638 666 | 
             
                  name = to_constant_name desc
         | 
| 639 667 | 
             
                  return false unless qualified_const_defined?(name)
         | 
| 640 668 | 
             
                  autoloaded_constants.include?(name)
         | 
| @@ -690,7 +718,7 @@ module ActiveSupport #:nodoc: | |
| 690 718 | 
             
                  when String then desc.sub(/^::/, "")
         | 
| 691 719 | 
             
                  when Symbol then desc.to_s
         | 
| 692 720 | 
             
                  when Module
         | 
| 693 | 
            -
                    desc | 
| 721 | 
            +
                    real_mod_name(desc) ||
         | 
| 694 722 | 
             
                      raise(ArgumentError, "Anonymous modules have no name to be referenced by")
         | 
| 695 723 | 
             
                  else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
         | 
| 696 724 | 
             
                  end
         | 
| @@ -764,6 +792,14 @@ module ActiveSupport #:nodoc: | |
| 764 792 | 
             
                def log(message)
         | 
| 765 793 | 
             
                  logger.debug("autoloading: #{message}") if logger && verbose
         | 
| 766 794 | 
             
                end
         | 
| 795 | 
            +
             | 
| 796 | 
            +
                private
         | 
| 797 | 
            +
             | 
| 798 | 
            +
                  # Returns the original name of a class or module even if `name` has been
         | 
| 799 | 
            +
                  # overridden.
         | 
| 800 | 
            +
                  def real_mod_name(mod)
         | 
| 801 | 
            +
                    UNBOUND_METHOD_MODULE_NAME.bind(mod).call
         | 
| 802 | 
            +
                  end
         | 
| 767 803 | 
             
              end
         | 
| 768 804 | 
             
            end
         | 
| 769 805 |  | 
| @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require "set"
         | 
| 3 4 | 
             
            require "active_support/core_ext/string/inflections"
         | 
| 4 5 |  | 
| 5 6 | 
             
            module ActiveSupport
         | 
| @@ -9,6 +10,8 @@ module ActiveSupport | |
| 9 10 | 
             
                    def clear
         | 
| 10 11 | 
             
                      Dependencies.unload_interlock do
         | 
| 11 12 | 
             
                        Rails.autoloaders.main.reload
         | 
| 13 | 
            +
                      rescue Zeitwerk::ReloadingDisabledError
         | 
| 14 | 
            +
                        raise "reloading is disabled because config.cache_classes is true"
         | 
| 12 15 | 
             
                      end
         | 
| 13 16 | 
             
                    end
         | 
| 14 17 |  | 
| @@ -21,12 +24,12 @@ module ActiveSupport | |
| 21 24 | 
             
                    end
         | 
| 22 25 |  | 
| 23 26 | 
             
                    def autoloaded_constants
         | 
| 24 | 
            -
                       | 
| 27 | 
            +
                      Rails.autoloaders.main.unloadable_cpaths
         | 
| 25 28 | 
             
                    end
         | 
| 26 29 |  | 
| 27 30 | 
             
                    def autoloaded?(object)
         | 
| 28 | 
            -
                      cpath = object.is_a?(Module) ? object | 
| 29 | 
            -
                      Rails.autoloaders. | 
| 31 | 
            +
                      cpath = object.is_a?(Module) ? real_mod_name(object) : object.to_s
         | 
| 32 | 
            +
                      Rails.autoloaders.main.unloadable_cpath?(cpath)
         | 
| 30 33 | 
             
                    end
         | 
| 31 34 |  | 
| 32 35 | 
             
                    def verbose=(verbose)
         | 
| @@ -39,55 +42,75 @@ module ActiveSupport | |
| 39 42 | 
             
                    end
         | 
| 40 43 | 
             
                  end
         | 
| 41 44 |  | 
| 45 | 
            +
                  module RequireDependency
         | 
| 46 | 
            +
                    def require_dependency(filename)
         | 
| 47 | 
            +
                      filename = filename.to_path if filename.respond_to?(:to_path)
         | 
| 48 | 
            +
                      if abspath = ActiveSupport::Dependencies.search_for_file(filename)
         | 
| 49 | 
            +
                        require abspath
         | 
| 50 | 
            +
                      else
         | 
| 51 | 
            +
                        require filename
         | 
| 52 | 
            +
                      end
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 42 56 | 
             
                  module Inflector
         | 
| 57 | 
            +
                    # Concurrent::Map is not needed. This is a private class, and overrides
         | 
| 58 | 
            +
                    # must be defined while the application boots.
         | 
| 59 | 
            +
                    @overrides = {}
         | 
| 60 | 
            +
             | 
| 43 61 | 
             
                    def self.camelize(basename, _abspath)
         | 
| 44 | 
            -
                      basename.camelize
         | 
| 62 | 
            +
                      @overrides[basename] || basename.camelize
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    def self.inflect(overrides)
         | 
| 66 | 
            +
                      @overrides.merge!(overrides)
         | 
| 45 67 | 
             
                    end
         | 
| 46 68 | 
             
                  end
         | 
| 47 69 |  | 
| 48 70 | 
             
                  class << self
         | 
| 49 | 
            -
                    def take_over
         | 
| 50 | 
            -
                      setup_autoloaders
         | 
| 51 | 
            -
                       | 
| 71 | 
            +
                    def take_over(enable_reloading:)
         | 
| 72 | 
            +
                      setup_autoloaders(enable_reloading)
         | 
| 73 | 
            +
                      freeze_paths
         | 
| 52 74 | 
             
                      decorate_dependencies
         | 
| 53 75 | 
             
                    end
         | 
| 54 76 |  | 
| 55 77 | 
             
                    private
         | 
| 56 78 |  | 
| 57 | 
            -
                      def setup_autoloaders
         | 
| 58 | 
            -
                        Rails.autoloaders.each do |autoloader|
         | 
| 59 | 
            -
                          autoloader.inflector = Inflector
         | 
| 60 | 
            -
                        end
         | 
| 61 | 
            -
             | 
| 79 | 
            +
                      def setup_autoloaders(enable_reloading)
         | 
| 62 80 | 
             
                        Dependencies.autoload_paths.each do |autoload_path|
         | 
| 63 81 | 
             
                          # Zeitwerk only accepts existing directories in `push_dir` to
         | 
| 64 82 | 
             
                          # prevent misconfigurations.
         | 
| 65 83 | 
             
                          next unless File.directory?(autoload_path)
         | 
| 66 84 |  | 
| 67 | 
            -
                           | 
| 68 | 
            -
                            Rails.autoloaders.once. | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
                           | 
| 85 | 
            +
                          autoloader = \
         | 
| 86 | 
            +
                            autoload_once?(autoload_path) ? Rails.autoloaders.once : Rails.autoloaders.main
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                          autoloader.push_dir(autoload_path)
         | 
| 89 | 
            +
                          autoloader.do_not_eager_load(autoload_path) unless eager_load?(autoload_path)
         | 
| 72 90 | 
             
                        end
         | 
| 73 91 |  | 
| 92 | 
            +
                        Rails.autoloaders.main.enable_reloading if enable_reloading
         | 
| 74 93 | 
             
                        Rails.autoloaders.each(&:setup)
         | 
| 75 94 | 
             
                      end
         | 
| 76 95 |  | 
| 77 96 | 
             
                      def autoload_once?(autoload_path)
         | 
| 78 | 
            -
                        Dependencies.autoload_once_paths.include?(autoload_path) | 
| 79 | 
            -
             | 
| 97 | 
            +
                        Dependencies.autoload_once_paths.include?(autoload_path)
         | 
| 98 | 
            +
                      end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                      def eager_load?(autoload_path)
         | 
| 101 | 
            +
                        Dependencies._eager_load_paths.member?(autoload_path)
         | 
| 80 102 | 
             
                      end
         | 
| 81 103 |  | 
| 82 | 
            -
                      def  | 
| 104 | 
            +
                      def freeze_paths
         | 
| 83 105 | 
             
                        Dependencies.autoload_paths.freeze
         | 
| 84 106 | 
             
                        Dependencies.autoload_once_paths.freeze
         | 
| 107 | 
            +
                        Dependencies._eager_load_paths.freeze
         | 
| 85 108 | 
             
                      end
         | 
| 86 109 |  | 
| 87 110 | 
             
                      def decorate_dependencies
         | 
| 88 111 | 
             
                        Dependencies.unhook!
         | 
| 89 112 | 
             
                        Dependencies.singleton_class.prepend(Decorations)
         | 
| 90 | 
            -
                        Object. | 
| 113 | 
            +
                        Object.prepend(RequireDependency)
         | 
| 91 114 | 
             
                      end
         | 
| 92 115 | 
             
                  end
         | 
| 93 116 | 
             
                end
         |