activesupport 5.1.7 → 7.0.4.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +259 -585
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +4 -2
  8. data/lib/active_support/backtrace_cleaner.rb +33 -5
  9. data/lib/active_support/benchmarkable.rb +5 -3
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +50 -43
  12. data/lib/active_support/cache/mem_cache_store.rb +194 -67
  13. data/lib/active_support/cache/memory_store.rb +70 -34
  14. data/lib/active_support/cache/null_store.rb +18 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +474 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +73 -50
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +556 -220
  19. data/lib/active_support/callbacks.rb +264 -159
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +81 -8
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
  23. data/lib/active_support/concurrency/share_lock.rb +4 -3
  24. data/lib/active_support/configurable.rb +17 -16
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +18 -8
  27. data/lib/active_support/core_ext/array/conversions.rb +20 -17
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +8 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +4 -2
  33. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  34. data/lib/active_support/core_ext/array.rb +4 -1
  35. data/lib/active_support/core_ext/benchmark.rb +4 -2
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
  37. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  38. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  40. data/lib/active_support/core_ext/class/subclasses.rb +10 -24
  41. data/lib/active_support/core_ext/class.rb +2 -0
  42. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  43. data/lib/active_support/core_ext/date/blank.rb +3 -1
  44. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  45. data/lib/active_support/core_ext/date/conversions.rb +24 -22
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +2 -0
  48. data/lib/active_support/core_ext/date.rb +3 -0
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +3 -1
  54. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  56. data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +3 -0
  59. data/lib/active_support/core_ext/digest/uuid.rb +42 -14
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +244 -72
  62. data/lib/active_support/core_ext/file/atomic.rb +6 -2
  63. data/lib/active_support/core_ext/file.rb +2 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +7 -6
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +4 -2
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +4 -31
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  72. data/lib/active_support/core_ext/hash.rb +3 -2
  73. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +7 -14
  76. data/lib/active_support/core_ext/integer.rb +2 -0
  77. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
  80. data/lib/active_support/core_ext/kernel.rb +2 -1
  81. data/lib/active_support/core_ext/load_error.rb +3 -8
  82. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  83. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  84. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
  87. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  88. data/lib/active_support/core_ext/module/delegation.rb +97 -58
  89. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  90. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  93. data/lib/active_support/core_ext/module.rb +3 -1
  94. data/lib/active_support/core_ext/name_error.rb +30 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  99. data/lib/active_support/core_ext/numeric.rb +3 -1
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +15 -5
  102. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  103. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  104. data/lib/active_support/core_ext/object/duplicable.rb +16 -110
  105. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  106. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  107. data/lib/active_support/core_ext/object/json.rb +51 -26
  108. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  109. data/lib/active_support/core_ext/object/to_query.rb +4 -2
  110. data/lib/active_support/core_ext/object/try.rb +26 -14
  111. data/lib/active_support/core_ext/object/with_options.rb +24 -3
  112. data/lib/active_support/core_ext/object.rb +2 -0
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +6 -3
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +3 -1
  121. data/lib/active_support/core_ext/range.rb +4 -1
  122. data/lib/active_support/core_ext/regexp.rb +10 -5
  123. data/lib/active_support/core_ext/securerandom.rb +25 -3
  124. data/lib/active_support/core_ext/string/access.rb +7 -16
  125. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  126. data/lib/active_support/core_ext/string/conversions.rb +5 -2
  127. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  128. data/lib/active_support/core_ext/string/filters.rb +44 -1
  129. data/lib/active_support/core_ext/string/indent.rb +2 -0
  130. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  133. data/lib/active_support/core_ext/string/output_safety.rb +135 -27
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +5 -1
  136. data/lib/active_support/core_ext/string/zones.rb +2 -0
  137. data/lib/active_support/core_ext/string.rb +2 -0
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  141. data/lib/active_support/core_ext/time/calculations.rb +81 -24
  142. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  143. data/lib/active_support/core_ext/time/conversions.rb +17 -12
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +12 -25
  146. data/lib/active_support/core_ext/time.rb +3 -0
  147. data/lib/active_support/core_ext/uri.rb +4 -23
  148. data/lib/active_support/core_ext.rb +4 -1
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +2 -0
  152. data/lib/active_support/dependencies/interlock.rb +12 -18
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +59 -715
  155. data/lib/active_support/deprecation/behaviors.rb +48 -13
  156. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  159. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
  161. data/lib/active_support/deprecation/reporting.rb +54 -9
  162. data/lib/active_support/deprecation.rb +10 -3
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +9 -9
  166. data/lib/active_support/duration/iso8601_serializer.rb +29 -15
  167. data/lib/active_support/duration.rb +158 -72
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +129 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +87 -122
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +46 -21
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +2 -0
  178. data/lib/active_support/file_update_checker.rb +2 -1
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +7 -5
  181. data/lib/active_support/gzip.rb +2 -0
  182. data/lib/active_support/hash_with_indifferent_access.rb +126 -42
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +5 -1
  185. data/lib/active_support/i18n_railtie.rb +19 -14
  186. data/lib/active_support/inflections.rb +2 -0
  187. data/lib/active_support/inflector/inflections.rb +41 -14
  188. data/lib/active_support/inflector/methods.rb +73 -87
  189. data/lib/active_support/inflector/transliterate.rb +56 -18
  190. data/lib/active_support/inflector.rb +2 -0
  191. data/lib/active_support/isolated_execution_state.rb +72 -0
  192. data/lib/active_support/json/decoding.rb +27 -26
  193. data/lib/active_support/json/encoding.rb +16 -6
  194. data/lib/active_support/json.rb +2 -0
  195. data/lib/active_support/key_generator.rb +25 -38
  196. data/lib/active_support/lazy_load_hooks.rb +35 -6
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +8 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +4 -2
  200. data/lib/active_support/log_subscriber.rb +54 -13
  201. data/lib/active_support/logger.rb +4 -17
  202. data/lib/active_support/logger_silence.rb +13 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +48 -10
  204. data/lib/active_support/message_encryptor.rb +111 -37
  205. data/lib/active_support/message_verifier.rb +124 -21
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +19 -76
  210. data/lib/active_support/multibyte/unicode.rb +9 -331
  211. data/lib/active_support/multibyte.rb +3 -1
  212. data/lib/active_support/notifications/fanout.rb +165 -37
  213. data/lib/active_support/notifications/instrumenter.rb +92 -11
  214. data/lib/active_support/notifications.rb +96 -30
  215. data/lib/active_support/number_helper/number_converter.rb +8 -9
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  223. data/lib/active_support/number_helper/rounding_helper.rb +16 -34
  224. data/lib/active_support/number_helper.rb +38 -12
  225. data/lib/active_support/option_merger.rb +19 -6
  226. data/lib/active_support/ordered_hash.rb +4 -2
  227. data/lib/active_support/ordered_options.rb +18 -6
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +8 -1
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +3 -10
  232. data/lib/active_support/railtie.rb +112 -11
  233. data/lib/active_support/reloader.rb +12 -11
  234. data/lib/active_support/rescuable.rb +19 -18
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +26 -15
  238. data/lib/active_support/string_inquirer.rb +4 -3
  239. data/lib/active_support/subscriber.rb +81 -42
  240. data/lib/active_support/tagged_logging.rb +45 -9
  241. data/lib/active_support/test_case.rb +86 -2
  242. data/lib/active_support/testing/assertions.rb +89 -21
  243. data/lib/active_support/testing/autorun.rb +2 -0
  244. data/lib/active_support/testing/constant_lookup.rb +2 -0
  245. data/lib/active_support/testing/declarative.rb +2 -0
  246. data/lib/active_support/testing/deprecation.rb +54 -2
  247. data/lib/active_support/testing/file_fixtures.rb +4 -0
  248. data/lib/active_support/testing/isolation.rb +6 -4
  249. data/lib/active_support/testing/method_call_assertions.rb +34 -5
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  255. data/lib/active_support/testing/stream.rb +6 -7
  256. data/lib/active_support/testing/tagged_logging.rb +3 -1
  257. data/lib/active_support/testing/time_helpers.rb +91 -15
  258. data/lib/active_support/time.rb +2 -0
  259. data/lib/active_support/time_with_zone.rb +168 -56
  260. data/lib/active_support/values/time_zone.rb +85 -37
  261. data/lib/active_support/version.rb +3 -1
  262. data/lib/active_support/xml_mini/jdom.rb +6 -5
  263. data/lib/active_support/xml_mini/libxml.rb +9 -7
  264. data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
  265. data/lib/active_support/xml_mini/nokogiri.rb +8 -6
  266. data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
  267. data/lib/active_support/xml_mini/rexml.rb +13 -4
  268. data/lib/active_support/xml_mini.rb +10 -15
  269. data/lib/active_support.rb +30 -9
  270. metadata +76 -35
  271. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  272. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  273. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  274. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  275. data/lib/active_support/core_ext/marshal.rb +0 -22
  276. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  277. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  278. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  279. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,60 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "weakref"
4
+ require "active_support/ruby_features"
5
+
1
6
  module ActiveSupport
2
7
  # This module provides an internal implementation to track descendants
3
8
  # which is faster than iterating through ObjectSpace.
4
9
  module DescendantsTracker
5
- @@direct_descendants = {}
6
-
7
10
  class << self
8
11
  def direct_descendants(klass)
9
- @@direct_descendants[klass] || []
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)
10
17
  end
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
37
+
38
+ def [](object)
39
+ @map.key?(object.object_id)
40
+ end
11
41
 
12
- def descendants(klass)
13
- arr = []
14
- accumulate_descendants(klass, arr)
15
- arr
42
+ def []=(object, _present)
43
+ @map[object.object_id] = object
44
+ end
45
+ end
46
+ WeakSet.new
16
47
  end
17
48
 
18
- def clear
19
- if defined? ActiveSupport::Dependencies
20
- @@direct_descendants.each do |klass, descendants|
21
- if ActiveSupport::Dependencies.autoloaded?(klass)
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
73
+ end
74
+ end
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
86
+ end
87
+
88
+ def descendants
89
+ subclasses.concat(subclasses.flat_map(&:descendants))
90
+ end
91
+
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)
22
123
  @@direct_descendants.delete(klass)
23
124
  else
24
- descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
125
+ direct_descendants_of_klass.reject! do |direct_descendant_of_class|
126
+ classes.member?(direct_descendant_of_class)
127
+ end
25
128
  end
26
129
  end
27
- else
28
- @@direct_descendants.clear
29
130
  end
131
+
132
+ def native? # :nodoc:
133
+ false
134
+ end
135
+
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
141
+
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
30
151
  end
31
152
 
32
- # This is the only method that is not thread safe, but is only ever called
33
- # during the eager loading phase.
34
- def store_inherited(klass, descendant)
35
- (@@direct_descendants[klass] ||= []) << descendant
153
+ def inherited(base)
154
+ DescendantsTracker.store_inherited(self, base)
155
+ super
36
156
  end
37
157
 
38
- private
39
- def accumulate_descendants(klass, acc)
40
- if direct_descendants = @@direct_descendants[klass]
41
- acc.concat(direct_descendants)
42
- direct_descendants.each { |direct_descendant| accumulate_descendants(direct_descendant, acc) }
43
- end
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)
44
164
  end
45
- end
46
165
 
47
- def inherited(base)
48
- DescendantsTracker.store_inherited(self, base)
49
- super
50
- end
166
+ def subclasses
167
+ DescendantsTracker.subclasses(self)
168
+ end
51
169
 
52
- def direct_descendants
53
- DescendantsTracker.direct_descendants(self)
54
- end
170
+ def descendants
171
+ DescendantsTracker.descendants(self)
172
+ end
55
173
 
56
- def descendants
57
- DescendantsTracker.descendants(self)
174
+ # DescendantsArray is an array that contains weak references to classes.
175
+ class DescendantsArray # :nodoc:
176
+ include Enumerable
177
+
178
+ def initialize
179
+ @refs = []
180
+ end
181
+
182
+ def initialize_copy(orig)
183
+ @refs = @refs.dup
184
+ end
185
+
186
+ def <<(klass)
187
+ @refs << WeakRef.new(klass)
188
+ end
189
+
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
214
+ end
215
+ end
58
216
  end
59
217
  end
60
218
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+
5
+ module ActiveSupport
6
+ class Digest # :nodoc:
7
+ class << self
8
+ def hash_digest_class
9
+ @hash_digest_class ||= OpenSSL::Digest::MD5
10
+ end
11
+
12
+ def hash_digest_class=(klass)
13
+ raise ArgumentError, "#{klass} is expected to implement hexdigest class method" unless klass.respond_to?(:hexdigest)
14
+ @hash_digest_class = klass
15
+ end
16
+
17
+ def hexdigest(arg)
18
+ hash_digest_class.hexdigest(arg)[0...32]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,25 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "strscan"
2
- require "active_support/core_ext/regexp"
3
4
 
4
5
  module ActiveSupport
5
6
  class Duration
6
7
  # Parses a string formatted according to ISO 8601 Duration into the hash.
7
8
  #
8
- # See {ISO 8601}[http://en.wikipedia.org/wiki/ISO_8601#Durations] for more information.
9
+ # See {ISO 8601}[https://en.wikipedia.org/wiki/ISO_8601#Durations] for more information.
9
10
  #
10
11
  # This parser allows negative parts to be present in pattern.
11
12
  class ISO8601Parser # :nodoc:
12
13
  class ParsingError < ::ArgumentError; end
13
14
 
14
15
  PERIOD_OR_COMMA = /\.|,/
15
- PERIOD = ".".freeze
16
- COMMA = ",".freeze
16
+ PERIOD = "."
17
+ COMMA = ","
17
18
 
18
- SIGN_MARKER = /\A\-|\+|/
19
+ SIGN_MARKER = /\A-|\+|/
19
20
  DATE_MARKER = /P/
20
21
  TIME_MARKER = /T/
21
- DATE_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
22
- TIME_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(H|M|S)/
22
+ DATE_COMPONENT = /(-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
23
+ TIME_COMPONENT = /(-?\d+(?:[.,]\d+)?)(H|M|S)/
23
24
 
24
25
  DATE_TO_PART = { "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days }
25
26
  TIME_TO_PART = { "H" => :hours, "M" => :minutes, "S" => :seconds }
@@ -79,7 +80,6 @@ module ActiveSupport
79
80
  end
80
81
 
81
82
  private
82
-
83
83
  def finished?
84
84
  scanner.eos?
85
85
  end
@@ -116,7 +116,7 @@ module ActiveSupport
116
116
  raise_parsing_error "(only last part can be fractional)"
117
117
  end
118
118
 
119
- return true
119
+ true
120
120
  end
121
121
  end
122
122
  end
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/blank"
2
- require "active_support/core_ext/hash/transform_values"
3
4
 
4
5
  module ActiveSupport
5
6
  class Duration
6
7
  # Serializes duration to string according to ISO 8601 Duration format.
7
8
  class ISO8601Serializer # :nodoc:
9
+ DATE_COMPONENTS = %i(years months days)
10
+
8
11
  def initialize(duration, precision: nil)
9
12
  @duration = duration
10
13
  @precision = precision
@@ -12,26 +15,25 @@ module ActiveSupport
12
15
 
13
16
  # Builds and returns output string.
14
17
  def serialize
15
- parts, sign = normalize
16
- return "PT0S".freeze if parts.empty?
18
+ parts = normalize
19
+ return "PT0S" if parts.empty?
17
20
 
18
- output = "P"
21
+ output = +"P"
19
22
  output << "#{parts[:years]}Y" if parts.key?(:years)
20
23
  output << "#{parts[:months]}M" if parts.key?(:months)
21
- output << "#{parts[:weeks]}W" if parts.key?(:weeks)
22
24
  output << "#{parts[:days]}D" if parts.key?(:days)
23
- time = ""
25
+ output << "#{parts[:weeks]}W" if parts.key?(:weeks)
26
+ time = +""
24
27
  time << "#{parts[:hours]}H" if parts.key?(:hours)
25
28
  time << "#{parts[:minutes]}M" if parts.key?(:minutes)
26
29
  if parts.key?(:seconds)
27
- time << "#{sprintf(@precision ? "%0.0#{@precision}f" : '%g', parts[:seconds])}S"
30
+ time << "#{format_seconds(parts[:seconds])}S"
28
31
  end
29
32
  output << "T#{time}" unless time.empty?
30
- "#{sign}#{output}"
33
+ output
31
34
  end
32
35
 
33
36
  private
34
-
35
37
  # Return pair of duration's parts and whole duration sign.
36
38
  # Parts are summarized (as they can become repetitive due to addition, etc).
37
39
  # Zero parts are removed as not significant.
@@ -40,13 +42,25 @@ module ActiveSupport
40
42
  parts = @duration.parts.each_with_object(Hash.new(0)) do |(k, v), p|
41
43
  p[k] += v unless v.zero?
42
44
  end
43
- # If all parts are negative - let's make a negative duration
44
- sign = ""
45
- if parts.values.all? { |v| v < 0 }
46
- sign = "-"
47
- parts.transform_values!(&:-@)
45
+
46
+ # Convert weeks to days and remove weeks if mixed with date parts
47
+ if week_mixed_with_date?(parts)
48
+ parts[:days] += parts.delete(:weeks) * SECONDS_PER_WEEK / SECONDS_PER_DAY
49
+ end
50
+
51
+ parts
52
+ end
53
+
54
+ def week_mixed_with_date?(parts)
55
+ parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
56
+ end
57
+
58
+ def format_seconds(seconds)
59
+ if @precision
60
+ sprintf("%0.0#{@precision}f", seconds)
61
+ else
62
+ seconds.to_s
48
63
  end
49
- [parts, sign]
50
64
  end
51
65
  end
52
66
  end