activesupport 4.2.11.1 → 6.0.3.1

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.

Files changed (263) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -411
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -7
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +34 -6
  9. data/lib/active_support/benchmarkable.rb +6 -4
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +58 -53
  12. data/lib/active_support/cache/mem_cache_store.rb +95 -91
  13. data/lib/active_support/cache/memory_store.rb +39 -36
  14. data/lib/active_support/cache/null_store.rb +11 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +75 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +331 -217
  19. data/lib/active_support/callbacks.rb +650 -592
  20. data/lib/active_support/concern.rb +35 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +226 -0
  23. data/lib/active_support/configurable.rb +13 -14
  24. data/lib/active_support/core_ext/array/access.rb +41 -1
  25. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  26. data/lib/active_support/core_ext/array/extract.rb +21 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  29. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
  31. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  32. data/lib/active_support/core_ext/array.rb +9 -6
  33. data/lib/active_support/core_ext/benchmark.rb +3 -1
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  35. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  36. data/lib/active_support/core_ext/class/attribute.rb +45 -31
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  39. data/lib/active_support/core_ext/class.rb +4 -3
  40. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  41. data/lib/active_support/core_ext/date/blank.rb +14 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  43. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  44. data/lib/active_support/core_ext/date/zones.rb +4 -2
  45. data/lib/active_support/core_ext/date.rb +6 -4
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  50. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  53. data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
  54. data/lib/active_support/core_ext/date_time.rb +7 -5
  55. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +114 -22
  58. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  59. data/lib/active_support/core_ext/file.rb +3 -1
  60. data/lib/active_support/core_ext/hash/compact.rb +4 -23
  61. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  63. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  64. data/lib/active_support/core_ext/hash/except.rb +12 -9
  65. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  66. data/lib/active_support/core_ext/hash/keys.rb +19 -42
  67. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  68. data/lib/active_support/core_ext/hash/slice.rb +5 -27
  69. data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
  70. data/lib/active_support/core_ext/hash.rb +10 -9
  71. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  72. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  73. data/lib/active_support/core_ext/integer/time.rb +11 -18
  74. data/lib/active_support/core_ext/integer.rb +5 -3
  75. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  76. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  78. data/lib/active_support/core_ext/kernel.rb +5 -5
  79. data/lib/active_support/core_ext/load_error.rb +3 -22
  80. data/lib/active_support/core_ext/marshal.rb +8 -8
  81. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  82. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  83. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  87. data/lib/active_support/core_ext/module/delegation.rb +133 -30
  88. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  89. data/lib/active_support/core_ext/module/introspection.rb +44 -19
  90. data/lib/active_support/core_ext/module/reachable.rb +5 -7
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/module.rb +13 -11
  94. data/lib/active_support/core_ext/name_error.rb +22 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
  97. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  99. data/lib/active_support/core_ext/numeric.rb +5 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  101. data/lib/active_support/core_ext/object/blank.rb +27 -3
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  104. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  105. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +51 -20
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  110. data/lib/active_support/core_ext/object/try.rb +81 -23
  111. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  112. data/lib/active_support/core_ext/object.rb +14 -13
  113. data/lib/active_support/core_ext/range/compare_range.rb +76 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  115. data/lib/active_support/core_ext/range/each.rb +18 -17
  116. data/lib/active_support/core_ext/range/include_range.rb +7 -21
  117. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  118. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  119. data/lib/active_support/core_ext/range.rb +7 -4
  120. data/lib/active_support/core_ext/regexp.rb +2 -0
  121. data/lib/active_support/core_ext/securerandom.rb +45 -0
  122. data/lib/active_support/core_ext/string/access.rb +16 -6
  123. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  124. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  125. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  126. data/lib/active_support/core_ext/string/filters.rb +48 -6
  127. data/lib/active_support/core_ext/string/indent.rb +6 -4
  128. data/lib/active_support/core_ext/string/inflections.rb +66 -24
  129. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  130. data/lib/active_support/core_ext/string/multibyte.rb +16 -7
  131. data/lib/active_support/core_ext/string/output_safety.rb +93 -40
  132. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  133. data/lib/active_support/core_ext/string/strip.rb +6 -5
  134. data/lib/active_support/core_ext/string/zones.rb +4 -2
  135. data/lib/active_support/core_ext/string.rb +15 -13
  136. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  137. data/lib/active_support/core_ext/time/calculations.rb +115 -52
  138. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  139. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  140. data/lib/active_support/core_ext/time/zones.rb +41 -7
  141. data/lib/active_support/core_ext/time.rb +7 -6
  142. data/lib/active_support/core_ext/uri.rb +6 -7
  143. data/lib/active_support/core_ext.rb +3 -1
  144. data/lib/active_support/current_attributes.rb +203 -0
  145. data/lib/active_support/dependencies/autoload.rb +2 -0
  146. data/lib/active_support/dependencies/interlock.rb +57 -0
  147. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  148. data/lib/active_support/dependencies.rb +208 -166
  149. data/lib/active_support/deprecation/behaviors.rb +44 -11
  150. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  151. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  152. data/lib/active_support/deprecation/method_wrappers.rb +61 -21
  153. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  154. data/lib/active_support/deprecation/reporting.rb +32 -12
  155. data/lib/active_support/deprecation.rb +12 -9
  156. data/lib/active_support/descendants_tracker.rb +57 -9
  157. data/lib/active_support/digest.rb +20 -0
  158. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  159. data/lib/active_support/duration/iso8601_serializer.rb +53 -0
  160. data/lib/active_support/duration.rb +315 -40
  161. data/lib/active_support/encrypted_configuration.rb +45 -0
  162. data/lib/active_support/encrypted_file.rb +100 -0
  163. data/lib/active_support/evented_file_update_checker.rb +234 -0
  164. data/lib/active_support/execution_wrapper.rb +129 -0
  165. data/lib/active_support/executor.rb +8 -0
  166. data/lib/active_support/file_update_checker.rb +62 -37
  167. data/lib/active_support/gem_version.rb +6 -4
  168. data/lib/active_support/gzip.rb +7 -5
  169. data/lib/active_support/hash_with_indifferent_access.rb +129 -30
  170. data/lib/active_support/i18n.rb +9 -6
  171. data/lib/active_support/i18n_railtie.rb +50 -14
  172. data/lib/active_support/inflections.rb +13 -11
  173. data/lib/active_support/inflector/inflections.rb +58 -13
  174. data/lib/active_support/inflector/methods.rb +159 -145
  175. data/lib/active_support/inflector/transliterate.rb +84 -34
  176. data/lib/active_support/inflector.rb +7 -5
  177. data/lib/active_support/json/decoding.rb +32 -30
  178. data/lib/active_support/json/encoding.rb +17 -60
  179. data/lib/active_support/json.rb +4 -2
  180. data/lib/active_support/key_generator.rb +11 -43
  181. data/lib/active_support/lazy_load_hooks.rb +53 -20
  182. data/lib/active_support/locale/en.rb +33 -0
  183. data/lib/active_support/locale/en.yml +2 -0
  184. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  185. data/lib/active_support/log_subscriber.rb +44 -19
  186. data/lib/active_support/logger.rb +9 -23
  187. data/lib/active_support/logger_silence.rb +32 -14
  188. data/lib/active_support/logger_thread_safe_level.rb +32 -8
  189. data/lib/active_support/message_encryptor.rb +166 -53
  190. data/lib/active_support/message_verifier.rb +149 -16
  191. data/lib/active_support/messages/metadata.rb +72 -0
  192. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  193. data/lib/active_support/messages/rotator.rb +56 -0
  194. data/lib/active_support/multibyte/chars.rb +56 -63
  195. data/lib/active_support/multibyte/unicode.rb +56 -290
  196. data/lib/active_support/multibyte.rb +4 -2
  197. data/lib/active_support/notifications/fanout.rb +109 -22
  198. data/lib/active_support/notifications/instrumenter.rb +107 -16
  199. data/lib/active_support/notifications.rb +51 -10
  200. data/lib/active_support/number_helper/number_converter.rb +16 -15
  201. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
  202. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  203. data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
  204. data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
  205. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  206. data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
  207. data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
  208. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  209. data/lib/active_support/number_helper.rb +105 -68
  210. data/lib/active_support/option_merger.rb +24 -4
  211. data/lib/active_support/ordered_hash.rb +7 -5
  212. data/lib/active_support/ordered_options.rb +27 -5
  213. data/lib/active_support/parameter_filter.rb +128 -0
  214. data/lib/active_support/per_thread_registry.rb +9 -4
  215. data/lib/active_support/proxy_object.rb +2 -0
  216. data/lib/active_support/rails.rb +10 -8
  217. data/lib/active_support/railtie.rb +43 -9
  218. data/lib/active_support/reloader.rb +130 -0
  219. data/lib/active_support/rescuable.rb +108 -53
  220. data/lib/active_support/security_utils.rb +15 -11
  221. data/lib/active_support/string_inquirer.rb +11 -4
  222. data/lib/active_support/subscriber.rb +74 -30
  223. data/lib/active_support/tagged_logging.rb +25 -13
  224. data/lib/active_support/test_case.rb +107 -44
  225. data/lib/active_support/testing/assertions.rb +151 -20
  226. data/lib/active_support/testing/autorun.rb +4 -2
  227. data/lib/active_support/testing/constant_lookup.rb +2 -1
  228. data/lib/active_support/testing/declarative.rb +3 -1
  229. data/lib/active_support/testing/deprecation.rb +13 -10
  230. data/lib/active_support/testing/file_fixtures.rb +38 -0
  231. data/lib/active_support/testing/isolation.rb +35 -26
  232. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  233. data/lib/active_support/testing/parallelization.rb +134 -0
  234. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  235. data/lib/active_support/testing/stream.rb +43 -0
  236. data/lib/active_support/testing/tagged_logging.rb +3 -1
  237. data/lib/active_support/testing/time_helpers.rb +84 -20
  238. data/lib/active_support/time.rb +14 -12
  239. data/lib/active_support/time_with_zone.rb +179 -39
  240. data/lib/active_support/values/time_zone.rb +203 -63
  241. data/lib/active_support/version.rb +3 -1
  242. data/lib/active_support/xml_mini/jdom.rb +116 -115
  243. data/lib/active_support/xml_mini/libxml.rb +16 -13
  244. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  245. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  246. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  247. data/lib/active_support/xml_mini/rexml.rb +11 -9
  248. data/lib/active_support/xml_mini.rb +38 -46
  249. data/lib/active_support.rb +13 -11
  250. metadata +84 -26
  251. data/lib/active_support/concurrency/latch.rb +0 -27
  252. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  253. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  254. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  255. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  256. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  257. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  258. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  259. data/lib/active_support/core_ext/object/itself.rb +0 -15
  260. data/lib/active_support/core_ext/struct.rb +0 -6
  261. data/lib/active_support/core_ext/thread.rb +0 -86
  262. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  263. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,17 +1,24 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module ActiveSupport
3
4
  module Multibyte
4
5
  module Unicode
5
-
6
6
  extend self
7
7
 
8
8
  # A list of all available normalization forms.
9
- # See http://www.unicode.org/reports/tr15/tr15-29.html for more
9
+ # See https://www.unicode.org/reports/tr15/tr15-29.html for more
10
10
  # information about normalization.
11
11
  NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
12
12
 
13
+ NORMALIZATION_FORM_ALIASES = { # :nodoc:
14
+ c: :nfc,
15
+ d: :nfd,
16
+ kc: :nfkc,
17
+ kd: :nfkd
18
+ }
19
+
13
20
  # The Unicode version that is supported by the implementation
14
- UNICODE_VERSION = '7.0.0'
21
+ UNICODE_VERSION = RbConfig::CONFIG["UNICODE_VERSION"]
15
22
 
16
23
  # The default normalization used for operations that require
17
24
  # normalization. It can be set to any of the normalizations
@@ -21,199 +28,48 @@ module ActiveSupport
21
28
  attr_accessor :default_normalization_form
22
29
  @default_normalization_form = :kc
23
30
 
24
- # Hangul character boundaries and properties
25
- HANGUL_SBASE = 0xAC00
26
- HANGUL_LBASE = 0x1100
27
- HANGUL_VBASE = 0x1161
28
- HANGUL_TBASE = 0x11A7
29
- HANGUL_LCOUNT = 19
30
- HANGUL_VCOUNT = 21
31
- HANGUL_TCOUNT = 28
32
- HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT
33
- HANGUL_SCOUNT = 11172
34
- HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT
35
- HANGUL_JAMO_FIRST = 0x1100
36
- HANGUL_JAMO_LAST = 0x11FF
37
-
38
- # All the unicode whitespace
39
- WHITESPACE = [
40
- (0x0009..0x000D).to_a, # White_Space # Cc [5] <control-0009>..<control-000D>
41
- 0x0020, # White_Space # Zs SPACE
42
- 0x0085, # White_Space # Cc <control-0085>
43
- 0x00A0, # White_Space # Zs NO-BREAK SPACE
44
- 0x1680, # White_Space # Zs OGHAM SPACE MARK
45
- (0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE
46
- 0x2028, # White_Space # Zl LINE SEPARATOR
47
- 0x2029, # White_Space # Zp PARAGRAPH SEPARATOR
48
- 0x202F, # White_Space # Zs NARROW NO-BREAK SPACE
49
- 0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE
50
- 0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
51
- ].flatten.freeze
52
-
53
- # BOM (byte order mark) can also be seen as whitespace, it's a
54
- # non-rendering character used to distinguish between little and big
55
- # endian. This is not an issue in utf-8, so it must be ignored.
56
- LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
57
-
58
- # Returns a regular expression pattern that matches the passed Unicode
59
- # codepoints.
60
- def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
61
- array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
62
- end
63
- TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
64
- LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
65
-
66
- # Detect whether the codepoint is in a certain character class. Returns
67
- # +true+ when it's in the specified character class and +false+ otherwise.
68
- # Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
69
- # <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
70
- #
71
- # Primarily used by the grapheme cluster support.
72
- def in_char_class?(codepoint, classes)
73
- classes.detect { |c| database.boundary[c] === codepoint } ? true : false
74
- end
75
-
76
31
  # Unpack the string at grapheme boundaries. Returns a list of character
77
32
  # lists.
78
33
  #
79
34
  # Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
80
35
  # Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
81
36
  def unpack_graphemes(string)
82
- codepoints = string.codepoints.to_a
83
- unpacked = []
84
- pos = 0
85
- marker = 0
86
- eoc = codepoints.length
87
- while(pos < eoc)
88
- pos += 1
89
- previous = codepoints[pos-1]
90
- current = codepoints[pos]
91
- if (
92
- # CR X LF
93
- ( previous == database.boundary[:cr] and current == database.boundary[:lf] ) or
94
- # L X (L|V|LV|LVT)
95
- ( database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or
96
- # (LV|V) X (V|T)
97
- ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or
98
- # (LVT|T) X (T)
99
- ( in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current ) or
100
- # X Extend
101
- (database.boundary[:extend] === current)
102
- )
103
- else
104
- unpacked << codepoints[marker..pos-1]
105
- marker = pos
106
- end
107
- end
108
- unpacked
37
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
38
+ ActiveSupport::Multibyte::Unicode#unpack_graphemes is deprecated and will be
39
+ removed from Rails 6.1. Use string.scan(/\X/).map(&:codepoints) instead.
40
+ MSG
41
+
42
+ string.scan(/\X/).map(&:codepoints)
109
43
  end
110
44
 
111
45
  # Reverse operation of unpack_graphemes.
112
46
  #
113
47
  # Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
114
48
  def pack_graphemes(unpacked)
115
- unpacked.flatten.pack('U*')
116
- end
49
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
50
+ ActiveSupport::Multibyte::Unicode#pack_graphemes is deprecated and will be
51
+ removed from Rails 6.1. Use array.flatten.pack("U*") instead.
52
+ MSG
117
53
 
118
- # Re-order codepoints so the string becomes canonical.
119
- def reorder_characters(codepoints)
120
- length = codepoints.length- 1
121
- pos = 0
122
- while pos < length do
123
- cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]]
124
- if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
125
- codepoints[pos..pos+1] = cp2.code, cp1.code
126
- pos += (pos > 0 ? -1 : 1)
127
- else
128
- pos += 1
129
- end
130
- end
131
- codepoints
54
+ unpacked.flatten.pack("U*")
132
55
  end
133
56
 
134
57
  # Decompose composed characters to the decomposed form.
135
58
  def decompose(type, codepoints)
136
- codepoints.inject([]) do |decomposed, cp|
137
- # if it's a hangul syllable starter character
138
- if HANGUL_SBASE <= cp and cp < HANGUL_SLAST
139
- sindex = cp - HANGUL_SBASE
140
- ncp = [] # new codepoints
141
- ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
142
- ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
143
- tindex = sindex % HANGUL_TCOUNT
144
- ncp << (HANGUL_TBASE + tindex) unless tindex == 0
145
- decomposed.concat ncp
146
- # if the codepoint is decomposable in with the current decomposition type
147
- elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatibility)
148
- decomposed.concat decompose(type, ncp.dup)
149
- else
150
- decomposed << cp
151
- end
59
+ if type == :compatibility
60
+ codepoints.pack("U*").unicode_normalize(:nfkd).codepoints
61
+ else
62
+ codepoints.pack("U*").unicode_normalize(:nfd).codepoints
152
63
  end
153
64
  end
154
65
 
155
66
  # Compose decomposed characters to the composed form.
156
67
  def compose(codepoints)
157
- pos = 0
158
- eoa = codepoints.length - 1
159
- starter_pos = 0
160
- starter_char = codepoints[0]
161
- previous_combining_class = -1
162
- while pos < eoa
163
- pos += 1
164
- lindex = starter_char - HANGUL_LBASE
165
- # -- Hangul
166
- if 0 <= lindex and lindex < HANGUL_LCOUNT
167
- vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
168
- if 0 <= vindex and vindex < HANGUL_VCOUNT
169
- tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
170
- if 0 <= tindex and tindex < HANGUL_TCOUNT
171
- j = starter_pos + 2
172
- eoa -= 2
173
- else
174
- tindex = 0
175
- j = starter_pos + 1
176
- eoa -= 1
177
- end
178
- codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE
179
- end
180
- starter_pos += 1
181
- starter_char = codepoints[starter_pos]
182
- # -- Other characters
183
- else
184
- current_char = codepoints[pos]
185
- current = database.codepoints[current_char]
186
- if current.combining_class > previous_combining_class
187
- if ref = database.composition_map[starter_char]
188
- composition = ref[current_char]
189
- else
190
- composition = nil
191
- end
192
- unless composition.nil?
193
- codepoints[starter_pos] = composition
194
- starter_char = composition
195
- codepoints.delete_at pos
196
- eoa -= 1
197
- pos -= 1
198
- previous_combining_class = -1
199
- else
200
- previous_combining_class = current.combining_class
201
- end
202
- else
203
- previous_combining_class = current.combining_class
204
- end
205
- if current.combining_class == 0
206
- starter_pos = pos
207
- starter_char = codepoints[pos]
208
- end
209
- end
210
- end
211
- codepoints
68
+ codepoints.pack("U*").unicode_normalize(:nfc).codepoints
212
69
  end
213
70
 
214
- # Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
215
71
  # Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars.
216
- if '<3'.respond_to?(:scrub) && !defined?(Rubinius)
72
+ if !defined?(Rubinius)
217
73
  # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
218
74
  # resulting in a valid UTF-8 string.
219
75
  #
@@ -236,7 +92,7 @@ module ActiveSupport
236
92
  reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE)
237
93
 
238
94
  source = string.dup
239
- out = ''.force_encoding(Encoding::UTF_16LE)
95
+ out = "".force_encoding(Encoding::UTF_16LE)
240
96
 
241
97
  loop do
242
98
  reader.primitive_convert(source, out)
@@ -258,133 +114,43 @@ module ActiveSupport
258
114
  # * <tt>string</tt> - The string to perform normalization on.
259
115
  # * <tt>form</tt> - The form you want to normalize in. Should be one of
260
116
  # the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
261
- # Default is ActiveSupport::Multibyte.default_normalization_form.
262
- def normalize(string, form=nil)
117
+ # Default is ActiveSupport::Multibyte::Unicode.default_normalization_form.
118
+ def normalize(string, form = nil)
263
119
  form ||= @default_normalization_form
264
- # See http://www.unicode.org/reports/tr15, Table 1
265
- codepoints = string.codepoints.to_a
266
- case form
267
- when :d
268
- reorder_characters(decompose(:canonical, codepoints))
269
- when :c
270
- compose(reorder_characters(decompose(:canonical, codepoints)))
271
- when :kd
272
- reorder_characters(decompose(:compatibility, codepoints))
273
- when :kc
274
- compose(reorder_characters(decompose(:compatibility, codepoints)))
275
- else
276
- raise ArgumentError, "#{form} is not a valid normalization variant", caller
277
- end.pack('U*')
278
- end
279
-
280
- def downcase(string)
281
- apply_mapping string, :lowercase_mapping
282
- end
283
-
284
- def upcase(string)
285
- apply_mapping string, :uppercase_mapping
286
- end
287
-
288
- def swapcase(string)
289
- apply_mapping string, :swapcase_mapping
290
- end
291
-
292
- # Holds data about a codepoint in the Unicode database.
293
- class Codepoint
294
- attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
295
-
296
- # Initializing Codepoint object with default values
297
- def initialize
298
- @combining_class = 0
299
- @uppercase_mapping = 0
300
- @lowercase_mapping = 0
301
- end
302
120
 
303
- def swapcase_mapping
304
- uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
121
+ # See https://www.unicode.org/reports/tr15, Table 1
122
+ if alias_form = NORMALIZATION_FORM_ALIASES[form]
123
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
124
+ ActiveSupport::Multibyte::Unicode#normalize is deprecated and will be
125
+ removed from Rails 6.1. Use String#unicode_normalize(:#{alias_form}) instead.
126
+ MSG
127
+
128
+ string.unicode_normalize(alias_form)
129
+ else
130
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
131
+ ActiveSupport::Multibyte::Unicode#normalize is deprecated and will be
132
+ removed from Rails 6.1. Use String#unicode_normalize instead.
133
+ MSG
134
+
135
+ raise ArgumentError, "#{form} is not a valid normalization variant", caller
305
136
  end
306
137
  end
307
138
 
308
- # Holds static data from the Unicode database.
309
- class UnicodeDatabase
310
- ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252
311
-
312
- attr_writer(*ATTRIBUTES)
313
-
314
- def initialize
315
- @codepoints = Hash.new(Codepoint.new)
316
- @composition_exclusion = []
317
- @composition_map = {}
318
- @boundary = {}
319
- @cp1252 = {}
320
- end
321
-
322
- # Lazy load the Unicode database so it's only loaded when it's actually used
323
- ATTRIBUTES.each do |attr_name|
324
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
325
- def #{attr_name} # def codepoints
326
- load # load
327
- @#{attr_name} # @codepoints
328
- end # end
329
- EOS
330
- end
331
-
332
- # Loads the Unicode database and returns all the internal objects of
333
- # UnicodeDatabase.
334
- def load
335
- begin
336
- @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
337
- rescue => e
338
- raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
339
- end
340
-
341
- # Redefine the === method so we can write shorter rules for grapheme cluster breaks
342
- @boundary.each do |k,_|
343
- @boundary[k].instance_eval do
344
- def ===(other)
345
- detect { |i| i === other } ? true : false
346
- end
347
- end if @boundary[k].kind_of?(Array)
348
- end
349
-
350
- # define attr_reader methods for the instance variables
351
- class << self
352
- attr_reader(*ATTRIBUTES)
353
- end
354
- end
139
+ %w(downcase upcase swapcase).each do |method|
140
+ define_method(method) do |string|
141
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
142
+ ActiveSupport::Multibyte::Unicode##{method} is deprecated and
143
+ will be removed from Rails 6.1. Use String methods directly.
144
+ MSG
355
145
 
356
- # Returns the directory in which the data files are stored.
357
- def self.dirname
358
- File.dirname(__FILE__) + '/../values/'
359
- end
360
-
361
- # Returns the filename for the data file for this version.
362
- def self.filename
363
- File.expand_path File.join(dirname, "unicode_tables.dat")
146
+ string.send(method)
364
147
  end
365
148
  end
366
149
 
367
150
  private
368
-
369
- def apply_mapping(string, mapping) #:nodoc:
370
- database.codepoints
371
- string.each_codepoint.map do |codepoint|
372
- cp = database.codepoints[codepoint]
373
- if cp and (ncp = cp.send(mapping)) and ncp > 0
374
- ncp
375
- else
376
- codepoint
377
- end
378
- end.pack('U*')
379
- end
380
-
381
- def recode_windows1252_chars(string)
382
- string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
383
- end
384
-
385
- def database
386
- @database ||= UnicodeDatabase.new
387
- end
151
+ def recode_windows1252_chars(string)
152
+ string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
153
+ end
388
154
  end
389
155
  end
390
156
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport #:nodoc:
2
4
  module Multibyte
3
- autoload :Chars, 'active_support/multibyte/chars'
4
- autoload :Unicode, 'active_support/multibyte/unicode'
5
+ autoload :Chars, "active_support/multibyte/chars"
6
+ autoload :Unicode, "active_support/multibyte/unicode"
5
7
 
6
8
  # The proxy class returned when calling mb_chars. You can use this accessor
7
9
  # to configure your own proxy class so you can support other encodings. See
@@ -1,5 +1,8 @@
1
- require 'mutex_m'
2
- require 'thread_safe'
1
+ # frozen_string_literal: true
2
+
3
+ require "mutex_m"
4
+ require "concurrent/map"
5
+ require "set"
3
6
 
4
7
  module ActiveSupport
5
8
  module Notifications
@@ -11,16 +14,22 @@ module ActiveSupport
11
14
  include Mutex_m
12
15
 
13
16
  def initialize
14
- @subscribers = []
15
- @listeners_for = ThreadSafe::Cache.new
17
+ @string_subscribers = Hash.new { |h, k| h[k] = [] }
18
+ @other_subscribers = []
19
+ @listeners_for = Concurrent::Map.new
16
20
  super
17
21
  end
18
22
 
19
- def subscribe(pattern = nil, block = Proc.new)
20
- subscriber = Subscribers.new pattern, block
23
+ def subscribe(pattern = nil, callable = nil, &block)
24
+ subscriber = Subscribers.new(pattern, callable || block)
21
25
  synchronize do
22
- @subscribers << subscriber
23
- @listeners_for.clear
26
+ if String === pattern
27
+ @string_subscribers[pattern] << subscriber
28
+ @listeners_for.delete(pattern)
29
+ else
30
+ @other_subscribers << subscriber
31
+ @listeners_for.clear
32
+ end
24
33
  end
25
34
  subscriber
26
35
  end
@@ -29,12 +38,19 @@ module ActiveSupport
29
38
  synchronize do
30
39
  case subscriber_or_name
31
40
  when String
32
- @subscribers.reject! { |s| s.matches?(subscriber_or_name) }
41
+ @string_subscribers[subscriber_or_name].clear
42
+ @listeners_for.delete(subscriber_or_name)
43
+ @other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) }
33
44
  else
34
- @subscribers.delete(subscriber_or_name)
45
+ pattern = subscriber_or_name.try(:pattern)
46
+ if String === pattern
47
+ @string_subscribers[pattern].delete(subscriber_or_name)
48
+ @listeners_for.delete(pattern)
49
+ else
50
+ @other_subscribers.delete(subscriber_or_name)
51
+ @listeners_for.clear
52
+ end
35
53
  end
36
-
37
- @listeners_for.clear
38
54
  end
39
55
  end
40
56
 
@@ -42,8 +58,8 @@ module ActiveSupport
42
58
  listeners_for(name).each { |s| s.start(name, id, payload) }
43
59
  end
44
60
 
45
- def finish(name, id, payload)
46
- listeners_for(name).each { |s| s.finish(name, id, payload) }
61
+ def finish(name, id, payload, listeners = listeners_for(name))
62
+ listeners.each { |s| s.finish(name, id, payload) }
47
63
  end
48
64
 
49
65
  def publish(name, *args)
@@ -51,10 +67,11 @@ module ActiveSupport
51
67
  end
52
68
 
53
69
  def listeners_for(name)
54
- # this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics)
70
+ # this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
55
71
  @listeners_for[name] || synchronize do
56
72
  # use synchronisation when accessing @subscribers
57
- @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
73
+ @listeners_for[name] ||=
74
+ @string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) }
58
75
  end
59
76
  end
60
77
 
@@ -68,12 +85,29 @@ module ActiveSupport
68
85
 
69
86
  module Subscribers # :nodoc:
70
87
  def self.new(pattern, listener)
71
- if listener.respond_to?(:start) and listener.respond_to?(:finish)
72
- subscriber = Evented.new pattern, listener
88
+ subscriber_class = Timed
89
+
90
+ if listener.respond_to?(:start) && listener.respond_to?(:finish)
91
+ subscriber_class = Evented
73
92
  else
74
- subscriber = Timed.new pattern, listener
93
+ # Doing all this to detect a block like `proc { |x| }` vs
94
+ # `proc { |*x| }` or `proc { |**x| }`
95
+ if listener.respond_to?(:parameters)
96
+ params = listener.parameters
97
+ if params.length == 1 && params.first.first == :opt
98
+ subscriber_class = EventObject
99
+ end
100
+ end
75
101
  end
76
102
 
103
+ wrap_all pattern, subscriber_class.new(pattern, listener)
104
+ end
105
+
106
+ def self.event_object_subscriber(pattern, block)
107
+ wrap_all pattern, EventObject.new(pattern, block)
108
+ end
109
+
110
+ def self.wrap_all(pattern, subscriber)
77
111
  unless pattern
78
112
  AllMessages.new(subscriber)
79
113
  else
@@ -81,9 +115,33 @@ module ActiveSupport
81
115
  end
82
116
  end
83
117
 
118
+ class Matcher #:nodoc:
119
+ attr_reader :pattern, :exclusions
120
+
121
+ def self.wrap(pattern)
122
+ return pattern if String === pattern
123
+ new(pattern)
124
+ end
125
+
126
+ def initialize(pattern)
127
+ @pattern = pattern
128
+ @exclusions = Set.new
129
+ end
130
+
131
+ def unsubscribe!(name)
132
+ exclusions << -name if pattern === name
133
+ end
134
+
135
+ def ===(name)
136
+ pattern === name && !exclusions.include?(name)
137
+ end
138
+ end
139
+
84
140
  class Evented #:nodoc:
141
+ attr_reader :pattern
142
+
85
143
  def initialize(pattern, delegate)
86
- @pattern = pattern
144
+ @pattern = Matcher.wrap(pattern)
87
145
  @delegate = delegate
88
146
  @can_publish = delegate.respond_to?(:publish)
89
147
  end
@@ -103,11 +161,15 @@ module ActiveSupport
103
161
  end
104
162
 
105
163
  def subscribed_to?(name)
106
- @pattern === name
164
+ pattern === name
107
165
  end
108
166
 
109
167
  def matches?(name)
110
- @pattern && @pattern === name
168
+ pattern && pattern === name
169
+ end
170
+
171
+ def unsubscribe!(name)
172
+ pattern.unsubscribe!(name)
111
173
  end
112
174
  end
113
175
 
@@ -128,6 +190,27 @@ module ActiveSupport
128
190
  end
129
191
  end
130
192
 
193
+ class EventObject < Evented
194
+ def start(name, id, payload)
195
+ stack = Thread.current[:_event_stack] ||= []
196
+ event = build_event name, id, payload
197
+ event.start!
198
+ stack.push event
199
+ end
200
+
201
+ def finish(name, id, payload)
202
+ stack = Thread.current[:_event_stack]
203
+ event = stack.pop
204
+ event.finish!
205
+ @delegate.call event
206
+ end
207
+
208
+ private
209
+ def build_event(name, id, payload)
210
+ ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
211
+ end
212
+ end
213
+
131
214
  class AllMessages # :nodoc:
132
215
  def initialize(delegate)
133
216
  @delegate = delegate
@@ -149,6 +232,10 @@ module ActiveSupport
149
232
  true
150
233
  end
151
234
 
235
+ def unsubscribe!(*)
236
+ false
237
+ end
238
+
152
239
  alias :matches? :===
153
240
  end
154
241
  end