activesupport 4.2.11.1 → 6.1.7.3

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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +464 -391
  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 +50 -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 +61 -55
  12. data/lib/active_support/cache/mem_cache_store.rb +115 -100
  13. data/lib/active_support/cache/memory_store.rb +81 -58
  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 +90 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +386 -225
  19. data/lib/active_support/callbacks.rb +661 -594
  20. data/lib/active_support/concern.rb +80 -7
  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 +16 -17
  24. data/lib/active_support/configuration_file.rb +51 -0
  25. data/lib/active_support/core_ext/array/access.rb +41 -1
  26. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  30. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  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 +5 -3
  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 +52 -48
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -25
  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 +27 -24
  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 +167 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +19 -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 +8 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +186 -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/conversions.rb +62 -41
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +13 -10
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  65. data/lib/active_support/core_ext/hash/keys.rb +20 -43
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +10 -9
  69. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +11 -18
  72. data/lib/active_support/core_ext/integer.rb +5 -3
  73. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +5 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +10 -8
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +63 -69
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +148 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +19 -14
  85. data/lib/active_support/core_ext/module/delegation.rb +164 -51
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +23 -22
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  90. data/lib/active_support/core_ext/module.rb +13 -11
  91. data/lib/active_support/core_ext/name_error.rb +51 -4
  92. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +133 -136
  94. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  95. data/lib/active_support/core_ext/numeric.rb +5 -3
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +27 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  99. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  100. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  101. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  102. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  103. data/lib/active_support/core_ext/object/json.rb +63 -21
  104. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  105. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  106. data/lib/active_support/core_ext/object/try.rb +81 -23
  107. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  108. data/lib/active_support/core_ext/object.rb +14 -13
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  111. data/lib/active_support/core_ext/range/each.rb +18 -17
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +7 -4
  115. data/lib/active_support/core_ext/regexp.rb +10 -1
  116. data/lib/active_support/core_ext/securerandom.rb +45 -0
  117. data/lib/active_support/core_ext/string/access.rb +9 -18
  118. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  119. data/lib/active_support/core_ext/string/conversions.rb +8 -4
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +48 -6
  122. data/lib/active_support/core_ext/string/indent.rb +6 -4
  123. data/lib/active_support/core_ext/string/inflections.rb +102 -26
  124. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  125. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  126. data/lib/active_support/core_ext/string/output_safety.rb +125 -40
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +6 -5
  129. data/lib/active_support/core_ext/string/zones.rb +4 -2
  130. data/lib/active_support/core_ext/string.rb +15 -13
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  134. data/lib/active_support/core_ext/time/calculations.rb +137 -53
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +22 -13
  137. data/lib/active_support/core_ext/time/zones.rb +41 -7
  138. data/lib/active_support/core_ext/time.rb +7 -6
  139. data/lib/active_support/core_ext/uri.rb +11 -8
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +210 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  146. data/lib/active_support/dependencies.rb +241 -175
  147. data/lib/active_support/deprecation/behaviors.rb +58 -12
  148. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  151. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  153. data/lib/active_support/deprecation/reporting.rb +81 -18
  154. data/lib/active_support/deprecation.rb +17 -9
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +22 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  158. data/lib/active_support/duration/iso8601_serializer.rb +59 -0
  159. data/lib/active_support/duration.rb +364 -39
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +170 -0
  164. data/lib/active_support/execution_wrapper.rb +132 -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/fork_tracker.rb +64 -0
  168. data/lib/active_support/gem_version.rb +7 -5
  169. data/lib/active_support/gzip.rb +7 -5
  170. data/lib/active_support/hash_with_indifferent_access.rb +171 -48
  171. data/lib/active_support/i18n.rb +9 -6
  172. data/lib/active_support/i18n_railtie.rb +47 -16
  173. data/lib/active_support/inflections.rb +13 -11
  174. data/lib/active_support/inflector/inflections.rb +58 -14
  175. data/lib/active_support/inflector/methods.rb +186 -169
  176. data/lib/active_support/inflector/transliterate.rb +83 -33
  177. data/lib/active_support/inflector.rb +7 -5
  178. data/lib/active_support/json/decoding.rb +32 -30
  179. data/lib/active_support/json/encoding.rb +22 -61
  180. data/lib/active_support/json.rb +4 -2
  181. data/lib/active_support/key_generator.rb +11 -43
  182. data/lib/active_support/lazy_load_hooks.rb +53 -20
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +9 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  186. data/lib/active_support/log_subscriber.rb +52 -19
  187. data/lib/active_support/logger.rb +10 -24
  188. data/lib/active_support/logger_silence.rb +14 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -10
  190. data/lib/active_support/message_encryptor.rb +167 -57
  191. data/lib/active_support/message_verifier.rb +151 -18
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +35 -80
  196. data/lib/active_support/multibyte/unicode.rb +22 -330
  197. data/lib/active_support/multibyte.rb +4 -2
  198. data/lib/active_support/notifications/fanout.rb +125 -23
  199. data/lib/active_support/notifications/instrumenter.rb +98 -16
  200. data/lib/active_support/notifications.rb +82 -14
  201. data/lib/active_support/number_helper/number_converter.rb +17 -16
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -14
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +14 -11
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +12 -10
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +29 -57
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +123 -71
  211. data/lib/active_support/option_merger.rb +25 -4
  212. data/lib/active_support/ordered_hash.rb +7 -5
  213. data/lib/active_support/ordered_options.rb +35 -7
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +10 -4
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +10 -11
  218. data/lib/active_support/railtie.rb +66 -10
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +112 -57
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +13 -4
  224. data/lib/active_support/subscriber.rb +80 -31
  225. data/lib/active_support/tagged_logging.rb +54 -17
  226. data/lib/active_support/test_case.rb +107 -44
  227. data/lib/active_support/testing/assertions.rb +158 -20
  228. data/lib/active_support/testing/autorun.rb +4 -2
  229. data/lib/active_support/testing/constant_lookup.rb +2 -1
  230. data/lib/active_support/testing/declarative.rb +3 -1
  231. data/lib/active_support/testing/deprecation.rb +13 -10
  232. data/lib/active_support/testing/file_fixtures.rb +38 -0
  233. data/lib/active_support/testing/isolation.rb +35 -26
  234. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  239. data/lib/active_support/testing/stream.rb +43 -0
  240. data/lib/active_support/testing/tagged_logging.rb +3 -1
  241. data/lib/active_support/testing/time_helpers.rb +121 -20
  242. data/lib/active_support/time.rb +14 -12
  243. data/lib/active_support/time_with_zone.rb +215 -51
  244. data/lib/active_support/values/time_zone.rb +223 -71
  245. data/lib/active_support/version.rb +3 -1
  246. data/lib/active_support/xml_mini/jdom.rb +116 -115
  247. data/lib/active_support/xml_mini/libxml.rb +16 -13
  248. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  249. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  250. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  251. data/lib/active_support/xml_mini/rexml.rb +18 -9
  252. data/lib/active_support/xml_mini.rb +38 -46
  253. data/lib/active_support.rb +25 -11
  254. metadata +100 -43
  255. data/lib/active_support/concurrency/latch.rb +0 -27
  256. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  257. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  258. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  259. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  260. data/lib/active_support/core_ext/hash/compact.rb +0 -24
  261. data/lib/active_support/core_ext/hash/transform_values.rb +0 -23
  262. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  263. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  264. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  265. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  266. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  267. data/lib/active_support/core_ext/object/itself.rb +0 -15
  268. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  269. data/lib/active_support/core_ext/struct.rb +0 -6
  270. data/lib/active_support/core_ext/thread.rb +0 -86
  271. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  272. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,226 +1,48 @@
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
- # A list of all available normalization forms.
9
- # See http://www.unicode.org/reports/tr15/tr15-29.html for more
10
- # information about normalization.
11
- NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
12
-
13
8
  # The Unicode version that is supported by the implementation
14
- UNICODE_VERSION = '7.0.0'
15
-
16
- # The default normalization used for operations that require
17
- # normalization. It can be set to any of the normalizations
18
- # in NORMALIZATION_FORMS.
19
- #
20
- # ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
21
- attr_accessor :default_normalization_form
22
- @default_normalization_form = :kc
23
-
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
9
+ UNICODE_VERSION = RbConfig::CONFIG["UNICODE_VERSION"]
75
10
 
76
- # Unpack the string at grapheme boundaries. Returns a list of character
77
- # lists.
78
- #
79
- # Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
80
- # Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
81
- 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
11
+ def default_normalization_form
12
+ ActiveSupport::Deprecation.warn(
13
+ "ActiveSupport::Multibyte::Unicode.default_normalization_form is deprecated and will be removed in Rails 7.0."
14
+ )
109
15
  end
110
16
 
111
- # Reverse operation of unpack_graphemes.
112
- #
113
- # Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
114
- def pack_graphemes(unpacked)
115
- unpacked.flatten.pack('U*')
116
- end
117
-
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
17
+ def default_normalization_form=(_)
18
+ ActiveSupport::Deprecation.warn(
19
+ "ActiveSupport::Multibyte::Unicode.default_normalization_form= is deprecated and will be removed in Rails 7.0."
20
+ )
132
21
  end
133
22
 
134
23
  # Decompose composed characters to the decomposed form.
135
24
  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
25
+ if type == :compatibility
26
+ codepoints.pack("U*").unicode_normalize(:nfkd).codepoints
27
+ else
28
+ codepoints.pack("U*").unicode_normalize(:nfd).codepoints
152
29
  end
153
30
  end
154
31
 
155
32
  # Compose decomposed characters to the composed form.
156
33
  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
34
+ codepoints.pack("U*").unicode_normalize(:nfc).codepoints
212
35
  end
213
36
 
214
- # Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
215
37
  # Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars.
216
- if '<3'.respond_to?(:scrub) && !defined?(Rubinius)
38
+ if !defined?(Rubinius)
217
39
  # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
218
40
  # resulting in a valid UTF-8 string.
219
41
  #
220
42
  # Passing +true+ will forcibly tidy all bytes, assuming that the string's
221
43
  # encoding is entirely CP1252 or ISO-8859-1.
222
44
  def tidy_bytes(string, force = false)
223
- return string if string.empty?
45
+ return string if string.empty? || string.ascii_only?
224
46
  return recode_windows1252_chars(string) if force
225
47
  string.scrub { |bad| recode_windows1252_chars(bad) }
226
48
  end
@@ -236,7 +58,7 @@ module ActiveSupport
236
58
  reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE)
237
59
 
238
60
  source = string.dup
239
- out = ''.force_encoding(Encoding::UTF_16LE)
61
+ out = "".force_encoding(Encoding::UTF_16LE)
240
62
 
241
63
  loop do
242
64
  reader.primitive_convert(source, out)
@@ -251,140 +73,10 @@ module ActiveSupport
251
73
  end
252
74
  end
253
75
 
254
- # Returns the KC normalization of the string by default. NFKC is
255
- # considered the best normalization form for passing strings to databases
256
- # and validations.
257
- #
258
- # * <tt>string</tt> - The string to perform normalization on.
259
- # * <tt>form</tt> - The form you want to normalize in. Should be one of
260
- # 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)
263
- 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
-
303
- def swapcase_mapping
304
- uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
305
- end
306
- end
307
-
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
355
-
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")
364
- end
365
- end
366
-
367
76
  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
77
+ def recode_windows1252_chars(string)
78
+ string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
79
+ end
388
80
  end
389
81
  end
390
82
  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,9 @@
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"
6
+ require "active_support/core_ext/object/try"
3
7
 
4
8
  module ActiveSupport
5
9
  module Notifications
@@ -11,16 +15,22 @@ module ActiveSupport
11
15
  include Mutex_m
12
16
 
13
17
  def initialize
14
- @subscribers = []
15
- @listeners_for = ThreadSafe::Cache.new
18
+ @string_subscribers = Hash.new { |h, k| h[k] = [] }
19
+ @other_subscribers = []
20
+ @listeners_for = Concurrent::Map.new
16
21
  super
17
22
  end
18
23
 
19
- def subscribe(pattern = nil, block = Proc.new)
20
- subscriber = Subscribers.new pattern, block
24
+ def subscribe(pattern = nil, callable = nil, monotonic: false, &block)
25
+ subscriber = Subscribers.new(pattern, callable || block, monotonic)
21
26
  synchronize do
22
- @subscribers << subscriber
23
- @listeners_for.clear
27
+ if String === pattern
28
+ @string_subscribers[pattern] << subscriber
29
+ @listeners_for.delete(pattern)
30
+ else
31
+ @other_subscribers << subscriber
32
+ @listeners_for.clear
33
+ end
24
34
  end
25
35
  subscriber
26
36
  end
@@ -29,12 +39,19 @@ module ActiveSupport
29
39
  synchronize do
30
40
  case subscriber_or_name
31
41
  when String
32
- @subscribers.reject! { |s| s.matches?(subscriber_or_name) }
42
+ @string_subscribers[subscriber_or_name].clear
43
+ @listeners_for.delete(subscriber_or_name)
44
+ @other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) }
33
45
  else
34
- @subscribers.delete(subscriber_or_name)
46
+ pattern = subscriber_or_name.try(:pattern)
47
+ if String === pattern
48
+ @string_subscribers[pattern].delete(subscriber_or_name)
49
+ @listeners_for.delete(pattern)
50
+ else
51
+ @other_subscribers.delete(subscriber_or_name)
52
+ @listeners_for.clear
53
+ end
35
54
  end
36
-
37
- @listeners_for.clear
38
55
  end
39
56
  end
40
57
 
@@ -42,8 +59,8 @@ module ActiveSupport
42
59
  listeners_for(name).each { |s| s.start(name, id, payload) }
43
60
  end
44
61
 
45
- def finish(name, id, payload)
46
- listeners_for(name).each { |s| s.finish(name, id, payload) }
62
+ def finish(name, id, payload, listeners = listeners_for(name))
63
+ listeners.each { |s| s.finish(name, id, payload) }
47
64
  end
48
65
 
49
66
  def publish(name, *args)
@@ -51,10 +68,11 @@ module ActiveSupport
51
68
  end
52
69
 
53
70
  def listeners_for(name)
54
- # this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics)
71
+ # this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
55
72
  @listeners_for[name] || synchronize do
56
73
  # use synchronisation when accessing @subscribers
57
- @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
74
+ @listeners_for[name] ||=
75
+ @string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) }
58
76
  end
59
77
  end
60
78
 
@@ -67,13 +85,26 @@ module ActiveSupport
67
85
  end
68
86
 
69
87
  module Subscribers # :nodoc:
70
- def self.new(pattern, listener)
71
- if listener.respond_to?(:start) and listener.respond_to?(:finish)
72
- subscriber = Evented.new pattern, listener
88
+ def self.new(pattern, listener, monotonic)
89
+ subscriber_class = monotonic ? MonotonicTimed : Timed
90
+
91
+ if listener.respond_to?(:start) && listener.respond_to?(:finish)
92
+ subscriber_class = Evented
73
93
  else
74
- subscriber = Timed.new pattern, listener
94
+ # Doing all this to detect a block like `proc { |x| }` vs
95
+ # `proc { |*x| }` or `proc { |**x| }`
96
+ if listener.respond_to?(:parameters)
97
+ params = listener.parameters
98
+ if params.length == 1 && params.first.first == :opt
99
+ subscriber_class = EventObject
100
+ end
101
+ end
75
102
  end
76
103
 
104
+ wrap_all pattern, subscriber_class.new(pattern, listener)
105
+ end
106
+
107
+ def self.wrap_all(pattern, subscriber)
77
108
  unless pattern
78
109
  AllMessages.new(subscriber)
79
110
  else
@@ -81,9 +112,33 @@ module ActiveSupport
81
112
  end
82
113
  end
83
114
 
115
+ class Matcher #:nodoc:
116
+ attr_reader :pattern, :exclusions
117
+
118
+ def self.wrap(pattern)
119
+ return pattern if String === pattern
120
+ new(pattern)
121
+ end
122
+
123
+ def initialize(pattern)
124
+ @pattern = pattern
125
+ @exclusions = Set.new
126
+ end
127
+
128
+ def unsubscribe!(name)
129
+ exclusions << -name if pattern === name
130
+ end
131
+
132
+ def ===(name)
133
+ pattern === name && !exclusions.include?(name)
134
+ end
135
+ end
136
+
84
137
  class Evented #:nodoc:
138
+ attr_reader :pattern
139
+
85
140
  def initialize(pattern, delegate)
86
- @pattern = pattern
141
+ @pattern = Matcher.wrap(pattern)
87
142
  @delegate = delegate
88
143
  @can_publish = delegate.respond_to?(:publish)
89
144
  end
@@ -103,11 +158,15 @@ module ActiveSupport
103
158
  end
104
159
 
105
160
  def subscribed_to?(name)
106
- @pattern === name
161
+ pattern === name
107
162
  end
108
163
 
109
164
  def matches?(name)
110
- @pattern && @pattern === name
165
+ pattern && pattern === name
166
+ end
167
+
168
+ def unsubscribe!(name)
169
+ pattern.unsubscribe!(name)
111
170
  end
112
171
  end
113
172
 
@@ -128,6 +187,45 @@ module ActiveSupport
128
187
  end
129
188
  end
130
189
 
190
+ class MonotonicTimed < Evented # :nodoc:
191
+ def publish(name, *args)
192
+ @delegate.call name, *args
193
+ end
194
+
195
+ def start(name, id, payload)
196
+ timestack = Thread.current[:_timestack_monotonic] ||= []
197
+ timestack.push Concurrent.monotonic_time
198
+ end
199
+
200
+ def finish(name, id, payload)
201
+ timestack = Thread.current[:_timestack_monotonic]
202
+ started = timestack.pop
203
+ @delegate.call(name, started, Concurrent.monotonic_time, id, payload)
204
+ end
205
+ end
206
+
207
+ class EventObject < Evented
208
+ def start(name, id, payload)
209
+ stack = Thread.current[:_event_stack] ||= []
210
+ event = build_event name, id, payload
211
+ event.start!
212
+ stack.push event
213
+ end
214
+
215
+ def finish(name, id, payload)
216
+ stack = Thread.current[:_event_stack]
217
+ event = stack.pop
218
+ event.payload = payload
219
+ event.finish!
220
+ @delegate.call event
221
+ end
222
+
223
+ private
224
+ def build_event(name, id, payload)
225
+ ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
226
+ end
227
+ end
228
+
131
229
  class AllMessages # :nodoc:
132
230
  def initialize(delegate)
133
231
  @delegate = delegate
@@ -149,6 +247,10 @@ module ActiveSupport
149
247
  true
150
248
  end
151
249
 
250
+ def unsubscribe!(*)
251
+ false
252
+ end
253
+
152
254
  alias :matches? :===
153
255
  end
154
256
  end