activesupport 6.1.4.1 → 7.0.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +325 -395
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/active_support/actionable_error.rb +1 -1
  6. data/lib/active_support/array_inquirer.rb +0 -2
  7. data/lib/active_support/backtrace_cleaner.rb +2 -2
  8. data/lib/active_support/benchmarkable.rb +2 -2
  9. data/lib/active_support/cache/file_store.rb +15 -9
  10. data/lib/active_support/cache/mem_cache_store.rb +148 -37
  11. data/lib/active_support/cache/memory_store.rb +24 -16
  12. data/lib/active_support/cache/null_store.rb +10 -2
  13. data/lib/active_support/cache/redis_cache_store.rb +68 -85
  14. data/lib/active_support/cache/strategy/local_cache.rb +38 -61
  15. data/lib/active_support/cache.rb +299 -147
  16. data/lib/active_support/callbacks.rb +184 -85
  17. data/lib/active_support/code_generator.rb +65 -0
  18. data/lib/active_support/concern.rb +5 -5
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
  20. data/lib/active_support/concurrency/share_lock.rb +2 -2
  21. data/lib/active_support/configurable.rb +8 -5
  22. data/lib/active_support/configuration_file.rb +1 -1
  23. data/lib/active_support/core_ext/array/access.rb +1 -5
  24. data/lib/active_support/core_ext/array/conversions.rb +13 -12
  25. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  27. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  28. data/lib/active_support/core_ext/array.rb +1 -0
  29. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  30. data/lib/active_support/core_ext/class/subclasses.rb +25 -17
  31. data/lib/active_support/core_ext/date/blank.rb +1 -1
  32. data/lib/active_support/core_ext/date/calculations.rb +24 -9
  33. data/lib/active_support/core_ext/date/conversions.rb +14 -14
  34. data/lib/active_support/core_ext/date/deprecated_conversions.rb +40 -0
  35. data/lib/active_support/core_ext/date.rb +1 -0
  36. data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
  37. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  38. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  39. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  40. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  41. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +36 -0
  42. data/lib/active_support/core_ext/date_time.rb +1 -0
  43. data/lib/active_support/core_ext/digest/uuid.rb +39 -13
  44. data/lib/active_support/core_ext/enumerable.rb +112 -38
  45. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  46. data/lib/active_support/core_ext/hash/conversions.rb +0 -1
  47. data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
  48. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  49. data/lib/active_support/core_ext/hash/keys.rb +4 -4
  50. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  51. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  52. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  53. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  54. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  55. data/lib/active_support/core_ext/module/delegation.rb +2 -8
  56. data/lib/active_support/core_ext/name_error.rb +2 -8
  57. data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
  58. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  59. data/lib/active_support/core_ext/numeric.rb +1 -0
  60. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  61. data/lib/active_support/core_ext/object/blank.rb +2 -2
  62. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  63. data/lib/active_support/core_ext/object/duplicable.rb +15 -4
  64. data/lib/active_support/core_ext/object/json.rb +30 -25
  65. data/lib/active_support/core_ext/object/to_query.rb +2 -4
  66. data/lib/active_support/core_ext/object/try.rb +20 -20
  67. data/lib/active_support/core_ext/object/with_options.rb +21 -2
  68. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  69. data/lib/active_support/core_ext/pathname.rb +3 -0
  70. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  71. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  72. data/lib/active_support/core_ext/range/deprecated_conversions.rb +36 -0
  73. data/lib/active_support/core_ext/range/each.rb +1 -1
  74. data/lib/active_support/core_ext/range/include_time_with_zone.rb +3 -26
  75. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  76. data/lib/active_support/core_ext/range.rb +1 -1
  77. data/lib/active_support/core_ext/securerandom.rb +1 -1
  78. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  79. data/lib/active_support/core_ext/string/filters.rb +1 -1
  80. data/lib/active_support/core_ext/string/inflections.rb +1 -5
  81. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  82. data/lib/active_support/core_ext/string/output_safety.rb +94 -38
  83. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  84. data/lib/active_support/core_ext/time/calculations.rb +13 -8
  85. data/lib/active_support/core_ext/time/conversions.rb +13 -12
  86. data/lib/active_support/core_ext/time/deprecated_conversions.rb +73 -0
  87. data/lib/active_support/core_ext/time/zones.rb +10 -26
  88. data/lib/active_support/core_ext/time.rb +1 -0
  89. data/lib/active_support/core_ext/uri.rb +3 -27
  90. data/lib/active_support/core_ext.rb +1 -0
  91. data/lib/active_support/current_attributes.rb +31 -14
  92. data/lib/active_support/dependencies/interlock.rb +10 -18
  93. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  94. data/lib/active_support/dependencies.rb +58 -788
  95. data/lib/active_support/deprecation/behaviors.rb +8 -5
  96. data/lib/active_support/deprecation/disallowed.rb +3 -3
  97. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  98. data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
  99. data/lib/active_support/deprecation.rb +2 -2
  100. data/lib/active_support/descendants_tracker.rb +174 -68
  101. data/lib/active_support/digest.rb +5 -3
  102. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  103. data/lib/active_support/duration/iso8601_serializer.rb +9 -1
  104. data/lib/active_support/duration.rb +81 -51
  105. data/lib/active_support/encrypted_configuration.rb +45 -3
  106. data/lib/active_support/encrypted_file.rb +21 -10
  107. data/lib/active_support/environment_inquirer.rb +1 -1
  108. data/lib/active_support/error_reporter.rb +117 -0
  109. data/lib/active_support/evented_file_update_checker.rb +20 -7
  110. data/lib/active_support/execution_context/test_helper.rb +13 -0
  111. data/lib/active_support/execution_context.rb +53 -0
  112. data/lib/active_support/execution_wrapper.rb +43 -21
  113. data/lib/active_support/executor/test_helper.rb +7 -0
  114. data/lib/active_support/fork_tracker.rb +19 -12
  115. data/lib/active_support/gem_version.rb +5 -5
  116. data/lib/active_support/hash_with_indifferent_access.rb +3 -1
  117. data/lib/active_support/html_safe_translation.rb +43 -0
  118. data/lib/active_support/i18n.rb +1 -0
  119. data/lib/active_support/i18n_railtie.rb +1 -1
  120. data/lib/active_support/inflector/inflections.rb +23 -7
  121. data/lib/active_support/inflector/methods.rb +29 -55
  122. data/lib/active_support/inflector/transliterate.rb +1 -1
  123. data/lib/active_support/isolated_execution_state.rb +72 -0
  124. data/lib/active_support/json/encoding.rb +3 -3
  125. data/lib/active_support/key_generator.rb +22 -5
  126. data/lib/active_support/lazy_load_hooks.rb +28 -4
  127. data/lib/active_support/locale/en.yml +1 -1
  128. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  129. data/lib/active_support/log_subscriber.rb +15 -5
  130. data/lib/active_support/logger_thread_safe_level.rb +4 -13
  131. data/lib/active_support/message_encryptor.rb +12 -6
  132. data/lib/active_support/message_verifier.rb +46 -14
  133. data/lib/active_support/messages/metadata.rb +2 -2
  134. data/lib/active_support/multibyte/chars.rb +10 -11
  135. data/lib/active_support/multibyte/unicode.rb +0 -12
  136. data/lib/active_support/multibyte.rb +1 -1
  137. data/lib/active_support/notifications/fanout.rb +91 -65
  138. data/lib/active_support/notifications/instrumenter.rb +32 -15
  139. data/lib/active_support/notifications.rb +23 -23
  140. data/lib/active_support/number_helper/number_converter.rb +1 -3
  141. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  142. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  143. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  144. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
  145. data/lib/active_support/number_helper/rounding_helper.rb +1 -5
  146. data/lib/active_support/number_helper.rb +4 -5
  147. data/lib/active_support/option_merger.rb +10 -18
  148. data/lib/active_support/ordered_hash.rb +1 -1
  149. data/lib/active_support/ordered_options.rb +1 -1
  150. data/lib/active_support/parameter_filter.rb +20 -11
  151. data/lib/active_support/per_thread_registry.rb +5 -0
  152. data/lib/active_support/railtie.rb +69 -19
  153. data/lib/active_support/reloader.rb +1 -1
  154. data/lib/active_support/rescuable.rb +12 -12
  155. data/lib/active_support/ruby_features.rb +7 -0
  156. data/lib/active_support/secure_compare_rotator.rb +2 -2
  157. data/lib/active_support/string_inquirer.rb +0 -2
  158. data/lib/active_support/subscriber.rb +7 -18
  159. data/lib/active_support/tagged_logging.rb +2 -2
  160. data/lib/active_support/test_case.rb +13 -21
  161. data/lib/active_support/testing/assertions.rb +36 -6
  162. data/lib/active_support/testing/deprecation.rb +52 -1
  163. data/lib/active_support/testing/isolation.rb +30 -29
  164. data/lib/active_support/testing/method_call_assertions.rb +5 -5
  165. data/lib/active_support/testing/parallelization/server.rb +4 -0
  166. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  167. data/lib/active_support/testing/parallelization.rb +4 -0
  168. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  169. data/lib/active_support/testing/stream.rb +3 -5
  170. data/lib/active_support/testing/tagged_logging.rb +1 -1
  171. data/lib/active_support/testing/time_helpers.rb +13 -2
  172. data/lib/active_support/time_with_zone.rb +43 -22
  173. data/lib/active_support/values/time_zone.rb +35 -14
  174. data/lib/active_support/version.rb +1 -1
  175. data/lib/active_support/xml_mini/jdom.rb +1 -1
  176. data/lib/active_support/xml_mini/libxml.rb +5 -5
  177. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  178. data/lib/active_support/xml_mini/nokogiri.rb +4 -4
  179. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  180. data/lib/active_support/xml_mini/rexml.rb +1 -1
  181. data/lib/active_support/xml_mini.rb +5 -4
  182. data/lib/active_support.rb +17 -1
  183. metadata +26 -23
  184. data/lib/active_support/core_ext/marshal.rb +0 -26
  185. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -3,7 +3,7 @@
3
3
  require "active_support/notifications"
4
4
 
5
5
  module ActiveSupport
6
- # Raised when <tt>ActiveSupport::Deprecation::Behavior#behavior</tt> is set with <tt>:raise</tt>.
6
+ # Raised when ActiveSupport::Deprecation::Behavior#behavior is set with <tt>:raise</tt>.
7
7
  # You would set <tt>:raise</tt>, as a behavior to raise errors and proactively report exceptions from deprecations.
8
8
  class DeprecationException < StandardError
9
9
  end
@@ -54,7 +54,7 @@ module ActiveSupport
54
54
  # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
55
55
  # [+log+] Log all deprecation warnings to +Rails.logger+.
56
56
  # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
57
- # [+silence+] Do nothing.
57
+ # [+silence+] Do nothing. On Rails, set <tt>config.active_support.report_deprecations = false</tt> to disable all behaviors.
58
58
  #
59
59
  # Setting behaviors only affects deprecations that happen after boot time.
60
60
  # For more information you can read the documentation of the +behavior=+ method.
@@ -93,6 +93,9 @@ module ActiveSupport
93
93
  # ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
94
94
  # # custom stuff
95
95
  # }
96
+ #
97
+ # If you are using Rails, you can set <tt>config.active_support.report_deprecations = false</tt> to disable
98
+ # all deprecation behaviors. This is similar to the +silence+ option but more performant.
96
99
  def behavior=(behavior)
97
100
  @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
98
101
  end
@@ -111,10 +114,10 @@ module ActiveSupport
111
114
  raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior."
112
115
  end
113
116
 
114
- if behavior.arity == 4 || behavior.arity == -1
115
- behavior
116
- else
117
+ if behavior.respond_to?(:arity) && behavior.arity == 2
117
118
  -> message, callstack, _, _ { behavior.call(message, callstack) }
119
+ else
120
+ behavior
118
121
  end
119
122
  end
120
123
  end
@@ -5,15 +5,15 @@ module ActiveSupport
5
5
  module Disallowed
6
6
  # Sets the criteria used to identify deprecation messages which should be
7
7
  # disallowed. Can be an array containing strings, symbols, or regular
8
- # expressions. (Symbols are treated as strings). These are compared against
8
+ # expressions. (Symbols are treated as strings.) These are compared against
9
9
  # the text of the generated deprecation warning.
10
10
  #
11
11
  # Additionally the scalar symbol +:all+ may be used to treat all
12
12
  # deprecations as disallowed.
13
13
  #
14
14
  # Deprecations matching a substring or regular expression will be handled
15
- # using the configured +ActiveSupport::Deprecation.disallowed_behavior+
16
- # rather than +ActiveSupport::Deprecation.behavior+
15
+ # using the configured Behavior#disallowed_behavior rather than
16
+ # Behavior#behavior.
17
17
  attr_writer :disallowed_warnings
18
18
 
19
19
  # Returns the configured criteria used to identify deprecation messages
@@ -62,9 +62,9 @@ module ActiveSupport
62
62
  target_module.module_eval do
63
63
  redefine_method(method_name) do |*args, &block|
64
64
  deprecator.deprecation_warning(method_name, message)
65
- method.bind(self).call(*args, &block)
65
+ method.bind_call(self, *args, &block)
66
66
  end
67
- ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
67
+ ruby2_keywords(method_name)
68
68
  end
69
69
  else
70
70
  mod ||= Module.new
@@ -73,7 +73,7 @@ module ActiveSupport
73
73
  deprecator.deprecation_warning(method_name, message)
74
74
  super(*args, &block)
75
75
  end
76
- ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
76
+ ruby2_keywords(method_name)
77
77
  end
78
78
  end
79
79
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveSupport
4
4
  class Deprecation
5
- class DeprecationProxy #:nodoc:
5
+ class DeprecationProxy # :nodoc:
6
6
  def self.new(*args, &block)
7
7
  object = args.first
8
8
 
@@ -26,7 +26,7 @@ module ActiveSupport
26
26
  end
27
27
 
28
28
  # DeprecatedObjectProxy transforms an object into a deprecated one. It
29
- # takes an object, a deprecation message and optionally a deprecator. The
29
+ # takes an object, a deprecation message, and optionally a deprecator. The
30
30
  # deprecator defaults to +ActiveSupport::Deprecator+ if none is specified.
31
31
  #
32
32
  # deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, "This object is now deprecated")
@@ -4,7 +4,7 @@ require "singleton"
4
4
 
5
5
  module ActiveSupport
6
6
  # \Deprecation specifies the API used by Rails to deprecate methods, instance
7
- # variables, objects and constants.
7
+ # variables, objects, and constants.
8
8
  class Deprecation
9
9
  # active_support.rb sets an autoload for ActiveSupport::Deprecation.
10
10
  #
@@ -38,7 +38,7 @@ module ActiveSupport
38
38
  # and the second is a library name.
39
39
  #
40
40
  # ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
41
- def initialize(deprecation_horizon = "6.2", gem_name = "Rails")
41
+ def initialize(deprecation_horizon = "7.1", gem_name = "Rails")
42
42
  self.gem_name = gem_name
43
43
  self.deprecation_horizon = deprecation_horizon
44
44
  # By default, warnings are not silenced and debugging is off.
@@ -1,110 +1,216 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "weakref"
4
+ require "active_support/ruby_features"
4
5
 
5
6
  module ActiveSupport
6
7
  # This module provides an internal implementation to track descendants
7
8
  # which is faster than iterating through ObjectSpace.
8
9
  module DescendantsTracker
9
- @@direct_descendants = {}
10
-
11
10
  class << self
12
11
  def direct_descendants(klass)
13
- descendants = @@direct_descendants[klass]
14
- descendants ? descendants.to_a : []
12
+ ActiveSupport::Deprecation.warn(<<~MSG)
13
+ ActiveSupport::DescendantsTracker.direct_descendants is deprecated and will be removed in Rails 7.1.
14
+ Use ActiveSupport::DescendantsTracker.subclasses instead.
15
+ MSG
16
+ subclasses(klass)
15
17
  end
16
- alias_method :subclasses, :direct_descendants
18
+ end
19
+
20
+ @clear_disabled = false
21
+
22
+ if RubyFeatures::CLASS_SUBCLASSES
23
+ @@excluded_descendants = if RUBY_ENGINE == "ruby"
24
+ # On MRI `ObjectSpace::WeakMap` keys are weak references.
25
+ # So we can simply use WeakMap as a `Set`.
26
+ ObjectSpace::WeakMap.new
27
+ else
28
+ # On TruffleRuby `ObjectSpace::WeakMap` keys are strong references.
29
+ # So we use `object_id` as a key and the actual object as a value.
30
+ #
31
+ # JRuby for now doesn't have Class#descendant, but when it will, it will likely
32
+ # have the same WeakMap semantic than Truffle so we future proof this as much as possible.
33
+ class WeakSet # :nodoc:
34
+ def initialize
35
+ @map = ObjectSpace::WeakMap.new
36
+ end
17
37
 
18
- def descendants(klass)
19
- arr = []
20
- accumulate_descendants(klass, arr)
21
- arr
38
+ def [](object)
39
+ @map.key?(object.object_id)
40
+ end
41
+
42
+ def []=(object, _present)
43
+ @map[object.object_id] = object
44
+ end
45
+ end
46
+ WeakSet.new
22
47
  end
23
48
 
24
- def clear
25
- if defined? ActiveSupport::Dependencies
26
- @@direct_descendants.each do |klass, descendants|
27
- if Dependencies.autoloaded?(klass)
28
- @@direct_descendants.delete(klass)
29
- else
30
- descendants.reject! { |v| Dependencies.autoloaded?(v) }
49
+ class << self
50
+ def disable_clear! # :nodoc:
51
+ unless @clear_disabled
52
+ @clear_disabled = true
53
+ remove_method(:subclasses)
54
+ @@excluded_descendants = nil
55
+ end
56
+ end
57
+
58
+ def subclasses(klass)
59
+ klass.subclasses
60
+ end
61
+
62
+ def descendants(klass)
63
+ klass.descendants
64
+ end
65
+
66
+ def clear(classes) # :nodoc:
67
+ raise "DescendantsTracker.clear was disabled because config.cache_classes = true" if @clear_disabled
68
+
69
+ classes.each do |klass|
70
+ @@excluded_descendants[klass] = true
71
+ klass.descendants.each do |descendant|
72
+ @@excluded_descendants[descendant] = true
31
73
  end
32
74
  end
33
- else
34
- @@direct_descendants.clear
35
75
  end
76
+
77
+ def native? # :nodoc:
78
+ true
79
+ end
80
+ end
81
+
82
+ def subclasses
83
+ subclasses = super
84
+ subclasses.reject! { |d| @@excluded_descendants[d] }
85
+ subclasses
36
86
  end
37
87
 
38
- # This is the only method that is not thread safe, but is only ever called
39
- # during the eager loading phase.
40
- def store_inherited(klass, descendant)
41
- (@@direct_descendants[klass] ||= DescendantsArray.new) << descendant
88
+ def descendants
89
+ subclasses.concat(subclasses.flat_map(&:descendants))
42
90
  end
43
91
 
44
- private
45
- def accumulate_descendants(klass, acc)
46
- if direct_descendants = @@direct_descendants[klass]
47
- direct_descendants.each do |direct_descendant|
48
- acc << direct_descendant
49
- accumulate_descendants(direct_descendant, acc)
92
+ def direct_descendants
93
+ ActiveSupport::Deprecation.warn(<<~MSG)
94
+ ActiveSupport::DescendantsTracker#direct_descendants is deprecated and will be removed in Rails 7.1.
95
+ Use #subclasses instead.
96
+ MSG
97
+ subclasses
98
+ end
99
+ else
100
+ @@direct_descendants = {}
101
+
102
+ class << self
103
+ def disable_clear! # :nodoc:
104
+ @clear_disabled = true
105
+ end
106
+
107
+ def subclasses(klass)
108
+ descendants = @@direct_descendants[klass]
109
+ descendants ? descendants.to_a : []
110
+ end
111
+
112
+ def descendants(klass)
113
+ arr = []
114
+ accumulate_descendants(klass, arr)
115
+ arr
116
+ end
117
+
118
+ def clear(classes) # :nodoc:
119
+ raise "DescendantsTracker.clear was disabled because config.cache_classes = true" if @clear_disabled
120
+
121
+ @@direct_descendants.each do |klass, direct_descendants_of_klass|
122
+ if classes.member?(klass)
123
+ @@direct_descendants.delete(klass)
124
+ else
125
+ direct_descendants_of_klass.reject! do |direct_descendant_of_class|
126
+ classes.member?(direct_descendant_of_class)
127
+ end
50
128
  end
51
129
  end
52
130
  end
53
- end
54
131
 
55
- def inherited(base)
56
- DescendantsTracker.store_inherited(self, base)
57
- super
58
- end
132
+ def native? # :nodoc:
133
+ false
134
+ end
59
135
 
60
- def direct_descendants
61
- DescendantsTracker.direct_descendants(self)
62
- end
63
- alias_method :subclasses, :direct_descendants
136
+ # This is the only method that is not thread safe, but is only ever called
137
+ # during the eager loading phase.
138
+ def store_inherited(klass, descendant)
139
+ (@@direct_descendants[klass] ||= DescendantsArray.new) << descendant
140
+ end
64
141
 
65
- def descendants
66
- DescendantsTracker.descendants(self)
67
- end
142
+ private
143
+ def accumulate_descendants(klass, acc)
144
+ if direct_descendants = @@direct_descendants[klass]
145
+ direct_descendants.each do |direct_descendant|
146
+ acc << direct_descendant
147
+ accumulate_descendants(direct_descendant, acc)
148
+ end
149
+ end
150
+ end
151
+ end
68
152
 
69
- # DescendantsArray is an array that contains weak references to classes.
70
- class DescendantsArray # :nodoc:
71
- include Enumerable
153
+ def inherited(base)
154
+ DescendantsTracker.store_inherited(self, base)
155
+ super
156
+ end
72
157
 
73
- def initialize
74
- @refs = []
158
+ def direct_descendants
159
+ ActiveSupport::Deprecation.warn(<<~MSG)
160
+ ActiveSupport::DescendantsTracker#direct_descendants is deprecated and will be removed in Rails 7.1.
161
+ Use #subclasses instead.
162
+ MSG
163
+ DescendantsTracker.subclasses(self)
75
164
  end
76
165
 
77
- def initialize_copy(orig)
78
- @refs = @refs.dup
166
+ def subclasses
167
+ DescendantsTracker.subclasses(self)
79
168
  end
80
169
 
81
- def <<(klass)
82
- @refs << WeakRef.new(klass)
170
+ def descendants
171
+ DescendantsTracker.descendants(self)
83
172
  end
84
173
 
85
- def each
86
- @refs.reject! do |ref|
87
- yield ref.__getobj__
88
- false
89
- rescue WeakRef::RefError
90
- true
174
+ # DescendantsArray is an array that contains weak references to classes.
175
+ class DescendantsArray # :nodoc:
176
+ include Enumerable
177
+
178
+ def initialize
179
+ @refs = []
91
180
  end
92
- self
93
- end
94
181
 
95
- def refs_size
96
- @refs.size
97
- end
182
+ def initialize_copy(orig)
183
+ @refs = @refs.dup
184
+ end
98
185
 
99
- def cleanup!
100
- @refs.delete_if { |ref| !ref.weakref_alive? }
101
- end
186
+ def <<(klass)
187
+ @refs << WeakRef.new(klass)
188
+ end
102
189
 
103
- def reject!
104
- @refs.reject! do |ref|
105
- yield ref.__getobj__
106
- rescue WeakRef::RefError
107
- true
190
+ def each
191
+ @refs.reject! do |ref|
192
+ yield ref.__getobj__
193
+ false
194
+ rescue WeakRef::RefError
195
+ true
196
+ end
197
+ self
198
+ end
199
+
200
+ def refs_size
201
+ @refs.size
202
+ end
203
+
204
+ def cleanup!
205
+ @refs.delete_if { |ref| !ref.weakref_alive? }
206
+ end
207
+
208
+ def reject!
209
+ @refs.reject! do |ref|
210
+ yield ref.__getobj__
211
+ rescue WeakRef::RefError
212
+ true
213
+ end
108
214
  end
109
215
  end
110
216
  end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "openssl"
4
+
3
5
  module ActiveSupport
4
- class Digest #:nodoc:
5
- class <<self
6
+ class Digest # :nodoc:
7
+ class << self
6
8
  def hash_digest_class
7
- @hash_digest_class ||= ::Digest::MD5
9
+ @hash_digest_class ||= OpenSSL::Digest::MD5
8
10
  end
9
11
 
10
12
  def hash_digest_class=(klass)
@@ -16,11 +16,11 @@ module ActiveSupport
16
16
  PERIOD = "."
17
17
  COMMA = ","
18
18
 
19
- SIGN_MARKER = /\A\-|\+|/
19
+ SIGN_MARKER = /\A-|\+|/
20
20
  DATE_MARKER = /P/
21
21
  TIME_MARKER = /T/
22
- DATE_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
23
- TIME_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(H|M|S)/
22
+ DATE_COMPONENT = /(-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
23
+ TIME_COMPONENT = /(-?\d+(?:[.,]\d+)?)(H|M|S)/
24
24
 
25
25
  DATE_TO_PART = { "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days }
26
26
  TIME_TO_PART = { "H" => :hours, "M" => :minutes, "S" => :seconds }
@@ -27,7 +27,7 @@ module ActiveSupport
27
27
  time << "#{parts[:hours]}H" if parts.key?(:hours)
28
28
  time << "#{parts[:minutes]}M" if parts.key?(:minutes)
29
29
  if parts.key?(:seconds)
30
- time << "#{sprintf(@precision ? "%0.0#{@precision}f" : '%g', parts[:seconds])}S"
30
+ time << "#{format_seconds(parts[:seconds])}S"
31
31
  end
32
32
  output << "T#{time}" unless time.empty?
33
33
  output
@@ -54,6 +54,14 @@ module ActiveSupport
54
54
  def week_mixed_with_date?(parts)
55
55
  parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
56
56
  end
57
+
58
+ def format_seconds(seconds)
59
+ if @precision
60
+ sprintf("%0.0#{@precision}f", seconds)
61
+ else
62
+ seconds.to_s
63
+ end
64
+ end
57
65
  end
58
66
  end
59
67
  end