activesupport 5.2.4.4 → 6.1.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 (187) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +353 -435
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/active_support.rb +14 -1
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/array_inquirer.rb +4 -2
  8. data/lib/active_support/backtrace_cleaner.rb +29 -3
  9. data/lib/active_support/benchmarkable.rb +1 -1
  10. data/lib/active_support/cache.rb +142 -78
  11. data/lib/active_support/cache/file_store.rb +33 -33
  12. data/lib/active_support/cache/mem_cache_store.rb +32 -20
  13. data/lib/active_support/cache/memory_store.rb +59 -33
  14. data/lib/active_support/cache/null_store.rb +8 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +70 -43
  16. data/lib/active_support/cache/strategy/local_cache.rb +41 -26
  17. data/lib/active_support/callbacks.rb +81 -64
  18. data/lib/active_support/concern.rb +70 -3
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  20. data/lib/active_support/concurrency/share_lock.rb +0 -1
  21. data/lib/active_support/configurable.rb +10 -14
  22. data/lib/active_support/configuration_file.rb +46 -0
  23. data/lib/active_support/core_ext.rb +1 -1
  24. data/lib/active_support/core_ext/array.rb +1 -1
  25. data/lib/active_support/core_ext/array/access.rb +18 -6
  26. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/benchmark.rb +2 -2
  29. data/lib/active_support/core_ext/class/attribute.rb +32 -47
  30. data/lib/active_support/core_ext/class/subclasses.rb +17 -38
  31. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  32. data/lib/active_support/core_ext/date/conversions.rb +2 -1
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +37 -47
  34. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  35. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  36. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  37. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  38. data/lib/active_support/core_ext/enumerable.rb +171 -75
  39. data/lib/active_support/core_ext/hash.rb +1 -2
  40. data/lib/active_support/core_ext/hash/conversions.rb +3 -3
  41. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  42. data/lib/active_support/core_ext/hash/except.rb +2 -2
  43. data/lib/active_support/core_ext/hash/keys.rb +1 -30
  44. data/lib/active_support/core_ext/hash/slice.rb +6 -27
  45. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  46. data/lib/active_support/core_ext/kernel.rb +0 -1
  47. data/lib/active_support/core_ext/load_error.rb +1 -1
  48. data/lib/active_support/core_ext/marshal.rb +2 -0
  49. data/lib/active_support/core_ext/module.rb +0 -1
  50. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  51. data/lib/active_support/core_ext/module/attribute_accessors.rb +30 -39
  52. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +17 -19
  53. data/lib/active_support/core_ext/module/concerning.rb +8 -2
  54. data/lib/active_support/core_ext/module/delegation.rb +76 -33
  55. data/lib/active_support/core_ext/module/introspection.rb +16 -15
  56. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  57. data/lib/active_support/core_ext/name_error.rb +29 -2
  58. data/lib/active_support/core_ext/numeric.rb +0 -1
  59. data/lib/active_support/core_ext/numeric/conversions.rb +129 -129
  60. data/lib/active_support/core_ext/object/blank.rb +1 -2
  61. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  62. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  63. data/lib/active_support/core_ext/object/json.rb +14 -2
  64. data/lib/active_support/core_ext/object/try.rb +17 -7
  65. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  66. data/lib/active_support/core_ext/range/compare_range.rb +34 -13
  67. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  68. data/lib/active_support/core_ext/range/each.rb +0 -1
  69. data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
  70. data/lib/active_support/core_ext/regexp.rb +8 -5
  71. data/lib/active_support/core_ext/securerandom.rb +23 -3
  72. data/lib/active_support/core_ext/string/access.rb +5 -16
  73. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  74. data/lib/active_support/core_ext/string/filters.rb +42 -1
  75. data/lib/active_support/core_ext/string/inflections.rb +45 -6
  76. data/lib/active_support/core_ext/string/inquiry.rb +1 -0
  77. data/lib/active_support/core_ext/string/multibyte.rb +6 -5
  78. data/lib/active_support/core_ext/string/output_safety.rb +70 -13
  79. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  80. data/lib/active_support/core_ext/string/strip.rb +3 -1
  81. data/lib/active_support/core_ext/symbol.rb +3 -0
  82. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  83. data/lib/active_support/core_ext/time/calculations.rb +50 -3
  84. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  85. data/lib/active_support/core_ext/uri.rb +6 -1
  86. data/lib/active_support/current_attributes.rb +15 -2
  87. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  88. data/lib/active_support/dependencies.rb +109 -34
  89. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  90. data/lib/active_support/deprecation.rb +6 -1
  91. data/lib/active_support/deprecation/behaviors.rb +16 -3
  92. data/lib/active_support/deprecation/disallowed.rb +56 -0
  93. data/lib/active_support/deprecation/instance_delegator.rb +0 -1
  94. data/lib/active_support/deprecation/method_wrappers.rb +18 -23
  95. data/lib/active_support/deprecation/proxy_wrappers.rb +29 -6
  96. data/lib/active_support/deprecation/reporting.rb +50 -7
  97. data/lib/active_support/descendants_tracker.rb +59 -9
  98. data/lib/active_support/duration.rb +90 -38
  99. data/lib/active_support/duration/iso8601_parser.rb +2 -4
  100. data/lib/active_support/duration/iso8601_serializer.rb +18 -14
  101. data/lib/active_support/encrypted_configuration.rb +0 -4
  102. data/lib/active_support/encrypted_file.rb +22 -4
  103. data/lib/active_support/environment_inquirer.rb +20 -0
  104. data/lib/active_support/evented_file_update_checker.rb +82 -117
  105. data/lib/active_support/execution_wrapper.rb +1 -0
  106. data/lib/active_support/file_update_checker.rb +0 -1
  107. data/lib/active_support/fork_tracker.rb +62 -0
  108. data/lib/active_support/gem_version.rb +4 -4
  109. data/lib/active_support/hash_with_indifferent_access.rb +64 -41
  110. data/lib/active_support/i18n.rb +1 -0
  111. data/lib/active_support/i18n_railtie.rb +15 -8
  112. data/lib/active_support/inflector/inflections.rb +2 -7
  113. data/lib/active_support/inflector/methods.rb +49 -58
  114. data/lib/active_support/inflector/transliterate.rb +47 -18
  115. data/lib/active_support/json/decoding.rb +25 -26
  116. data/lib/active_support/json/encoding.rb +11 -3
  117. data/lib/active_support/key_generator.rb +1 -33
  118. data/lib/active_support/lazy_load_hooks.rb +5 -2
  119. data/lib/active_support/locale/en.rb +33 -0
  120. data/lib/active_support/locale/en.yml +7 -3
  121. data/lib/active_support/log_subscriber.rb +39 -9
  122. data/lib/active_support/logger.rb +2 -17
  123. data/lib/active_support/logger_silence.rb +11 -19
  124. data/lib/active_support/logger_thread_safe_level.rb +50 -6
  125. data/lib/active_support/message_encryptor.rb +8 -13
  126. data/lib/active_support/message_verifier.rb +10 -10
  127. data/lib/active_support/messages/metadata.rb +11 -2
  128. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  129. data/lib/active_support/messages/rotator.rb +10 -9
  130. data/lib/active_support/multibyte/chars.rb +10 -68
  131. data/lib/active_support/multibyte/unicode.rb +15 -327
  132. data/lib/active_support/notifications.rb +72 -8
  133. data/lib/active_support/notifications/fanout.rb +116 -16
  134. data/lib/active_support/notifications/instrumenter.rb +71 -9
  135. data/lib/active_support/number_helper.rb +38 -12
  136. data/lib/active_support/number_helper/number_converter.rb +5 -6
  137. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -9
  138. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
  139. data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
  140. data/lib/active_support/number_helper/number_to_human_size_converter.rb +4 -3
  141. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  142. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  143. data/lib/active_support/number_helper/number_to_rounded_converter.rb +8 -7
  144. data/lib/active_support/number_helper/rounding_helper.rb +12 -28
  145. data/lib/active_support/option_merger.rb +22 -3
  146. data/lib/active_support/ordered_hash.rb +1 -1
  147. data/lib/active_support/ordered_options.rb +13 -3
  148. data/lib/active_support/parameter_filter.rb +133 -0
  149. data/lib/active_support/per_thread_registry.rb +1 -1
  150. data/lib/active_support/rails.rb +1 -10
  151. data/lib/active_support/railtie.rb +23 -1
  152. data/lib/active_support/reloader.rb +4 -5
  153. data/lib/active_support/rescuable.rb +4 -4
  154. data/lib/active_support/secure_compare_rotator.rb +51 -0
  155. data/lib/active_support/security_utils.rb +19 -12
  156. data/lib/active_support/string_inquirer.rb +4 -3
  157. data/lib/active_support/subscriber.rb +72 -28
  158. data/lib/active_support/tagged_logging.rb +42 -8
  159. data/lib/active_support/test_case.rb +91 -0
  160. data/lib/active_support/testing/assertions.rb +30 -9
  161. data/lib/active_support/testing/deprecation.rb +0 -1
  162. data/lib/active_support/testing/file_fixtures.rb +2 -0
  163. data/lib/active_support/testing/isolation.rb +2 -2
  164. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  165. data/lib/active_support/testing/parallelization.rb +51 -0
  166. data/lib/active_support/testing/parallelization/server.rb +78 -0
  167. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  168. data/lib/active_support/testing/stream.rb +1 -2
  169. data/lib/active_support/testing/time_helpers.rb +47 -12
  170. data/lib/active_support/time_with_zone.rb +81 -47
  171. data/lib/active_support/values/time_zone.rb +32 -17
  172. data/lib/active_support/xml_mini.rb +2 -10
  173. data/lib/active_support/xml_mini/jdom.rb +2 -3
  174. data/lib/active_support/xml_mini/libxml.rb +2 -2
  175. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  176. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  177. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  178. data/lib/active_support/xml_mini/rexml.rb +10 -3
  179. metadata +58 -32
  180. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
  181. data/lib/active_support/core_ext/hash/compact.rb +0 -29
  182. data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
  183. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  184. data/lib/active_support/core_ext/module/reachable.rb +0 -11
  185. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
  186. data/lib/active_support/core_ext/range/include_range.rb +0 -3
  187. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "active_support/core_ext/string/inflections"
5
+
6
+ module ActiveSupport
7
+ module Dependencies
8
+ module ZeitwerkIntegration # :nodoc: all
9
+ module Decorations
10
+ def clear
11
+ Dependencies.unload_interlock do
12
+ Rails.autoloaders.main.reload
13
+ rescue Zeitwerk::ReloadingDisabledError
14
+ raise "reloading is disabled because config.cache_classes is true"
15
+ end
16
+ end
17
+
18
+ def constantize(cpath)
19
+ ActiveSupport::Inflector.constantize(cpath)
20
+ end
21
+
22
+ def safe_constantize(cpath)
23
+ ActiveSupport::Inflector.safe_constantize(cpath)
24
+ end
25
+
26
+ def autoloaded_constants
27
+ Rails.autoloaders.main.unloadable_cpaths
28
+ end
29
+
30
+ def autoloaded?(object)
31
+ cpath = object.is_a?(Module) ? real_mod_name(object) : object.to_s
32
+ Rails.autoloaders.main.unloadable_cpath?(cpath)
33
+ end
34
+
35
+ def verbose=(verbose)
36
+ l = verbose ? logger || Rails.logger : nil
37
+ Rails.autoloaders.each { |autoloader| autoloader.logger = l }
38
+ end
39
+
40
+ def unhook!
41
+ :no_op
42
+ end
43
+ end
44
+
45
+ module RequireDependency
46
+ def require_dependency(filename)
47
+ filename = filename.to_path if filename.respond_to?(:to_path)
48
+ if abspath = ActiveSupport::Dependencies.search_for_file(filename)
49
+ require abspath
50
+ else
51
+ require filename
52
+ end
53
+ end
54
+ end
55
+
56
+ module Inflector
57
+ # Concurrent::Map is not needed. This is a private class, and overrides
58
+ # must be defined while the application boots.
59
+ @overrides = {}
60
+
61
+ def self.camelize(basename, _abspath)
62
+ @overrides[basename] || basename.camelize
63
+ end
64
+
65
+ def self.inflect(overrides)
66
+ @overrides.merge!(overrides)
67
+ end
68
+ end
69
+
70
+ class << self
71
+ def take_over(enable_reloading:)
72
+ setup_autoloaders(enable_reloading)
73
+ freeze_paths
74
+ decorate_dependencies
75
+ end
76
+
77
+ private
78
+ def setup_autoloaders(enable_reloading)
79
+ Dependencies.autoload_paths.each do |autoload_path|
80
+ # Zeitwerk only accepts existing directories in `push_dir` to
81
+ # prevent misconfigurations.
82
+ next unless File.directory?(autoload_path)
83
+
84
+ autoloader = \
85
+ autoload_once?(autoload_path) ? Rails.autoloaders.once : Rails.autoloaders.main
86
+
87
+ autoloader.push_dir(autoload_path)
88
+ autoloader.do_not_eager_load(autoload_path) unless eager_load?(autoload_path)
89
+ end
90
+
91
+ Rails.autoloaders.main.enable_reloading if enable_reloading
92
+ Rails.autoloaders.each(&:setup)
93
+ end
94
+
95
+ def autoload_once?(autoload_path)
96
+ Dependencies.autoload_once_paths.include?(autoload_path)
97
+ end
98
+
99
+ def eager_load?(autoload_path)
100
+ Dependencies._eager_load_paths.member?(autoload_path)
101
+ end
102
+
103
+ def freeze_paths
104
+ Dependencies.autoload_paths.freeze
105
+ Dependencies.autoload_once_paths.freeze
106
+ Dependencies._eager_load_paths.freeze
107
+ end
108
+
109
+ def decorate_dependencies
110
+ Dependencies.unhook!
111
+ Dependencies.singleton_class.prepend(Decorations)
112
+ Object.prepend(RequireDependency)
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -17,15 +17,18 @@ module ActiveSupport
17
17
  require "active_support/deprecation/instance_delegator"
18
18
  require "active_support/deprecation/behaviors"
19
19
  require "active_support/deprecation/reporting"
20
+ require "active_support/deprecation/disallowed"
20
21
  require "active_support/deprecation/constant_accessor"
21
22
  require "active_support/deprecation/method_wrappers"
22
23
  require "active_support/deprecation/proxy_wrappers"
23
24
  require "active_support/core_ext/module/deprecation"
25
+ require "concurrent/atomic/thread_local_var"
24
26
 
25
27
  include Singleton
26
28
  include InstanceDelegator
27
29
  include Behavior
28
30
  include Reporting
31
+ include Disallowed
29
32
  include MethodWrapper
30
33
 
31
34
  # The version number in which the deprecated behavior will be removed, by default.
@@ -35,12 +38,14 @@ module ActiveSupport
35
38
  # and the second is a library name.
36
39
  #
37
40
  # ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
38
- def initialize(deprecation_horizon = "6.0", gem_name = "Rails")
41
+ def initialize(deprecation_horizon = "6.2", gem_name = "Rails")
39
42
  self.gem_name = gem_name
40
43
  self.deprecation_horizon = deprecation_horizon
41
44
  # By default, warnings are not silenced and debugging is off.
42
45
  self.silenced = false
43
46
  self.debug = false
47
+ @silenced_thread = Concurrent::ThreadLocalVar.new(false)
48
+ @explicitly_allowed_warnings = Concurrent::ThreadLocalVar.new(nil)
44
49
  end
45
50
  end
46
51
  end
@@ -43,7 +43,7 @@ module ActiveSupport
43
43
  deprecation_horizon: deprecation_horizon)
44
44
  },
45
45
 
46
- silence: ->(message, callstack, deprecation_horizon, gem_name) {},
46
+ silence: ->(message, callstack, deprecation_horizon, gem_name) { },
47
47
  }
48
48
 
49
49
  # Behavior module allows to determine how to display deprecation messages.
@@ -51,7 +51,7 @@ module ActiveSupport
51
51
  # constant. Available behaviors are:
52
52
  #
53
53
  # [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
54
- # [+stderr+] Log all deprecation warnings to +$stderr+.
54
+ # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
55
55
  # [+log+] Log all deprecation warnings to +Rails.logger+.
56
56
  # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
57
57
  # [+silence+] Do nothing.
@@ -67,13 +67,18 @@ module ActiveSupport
67
67
  @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
68
68
  end
69
69
 
70
+ # Returns the current behavior for disallowed deprecations or if one isn't set, defaults to +:raise+.
71
+ def disallowed_behavior
72
+ @disallowed_behavior ||= [DEFAULT_BEHAVIORS[:raise]]
73
+ end
74
+
70
75
  # Sets the behavior to the specified value. Can be a single value, array,
71
76
  # or an object that responds to +call+.
72
77
  #
73
78
  # Available behaviors:
74
79
  #
75
80
  # [+raise+] Raise <tt>ActiveSupport::DeprecationException</tt>.
76
- # [+stderr+] Log all deprecation warnings to +$stderr+.
81
+ # [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
77
82
  # [+log+] Log all deprecation warnings to +Rails.logger+.
78
83
  # [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
79
84
  # [+silence+] Do nothing.
@@ -92,6 +97,14 @@ module ActiveSupport
92
97
  @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
93
98
  end
94
99
 
100
+ # Sets the behavior for disallowed deprecations (those configured by
101
+ # ActiveSupport::Deprecation.disallowed_warnings=) to the specified
102
+ # value. As with +behavior=+, this can be a single value, array, or an
103
+ # object that responds to +call+.
104
+ def disallowed_behavior=(behavior)
105
+ @disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
106
+ end
107
+
95
108
  private
96
109
  def arity_coerce(behavior)
97
110
  unless behavior.respond_to?(:call)
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ class Deprecation
5
+ module Disallowed
6
+ # Sets the criteria used to identify deprecation messages which should be
7
+ # disallowed. Can be an array containing strings, symbols, or regular
8
+ # expressions. (Symbols are treated as strings). These are compared against
9
+ # the text of the generated deprecation warning.
10
+ #
11
+ # Additionally the scalar symbol +:all+ may be used to treat all
12
+ # deprecations as disallowed.
13
+ #
14
+ # Deprecations matching a substring or regular expression will be handled
15
+ # using the configured +ActiveSupport::Deprecation.disallowed_behavior+
16
+ # rather than +ActiveSupport::Deprecation.behavior+
17
+ attr_writer :disallowed_warnings
18
+
19
+ # Returns the configured criteria used to identify deprecation messages
20
+ # which should be treated as disallowed.
21
+ def disallowed_warnings
22
+ @disallowed_warnings ||= []
23
+ end
24
+
25
+ private
26
+ def deprecation_disallowed?(message)
27
+ disallowed = ActiveSupport::Deprecation.disallowed_warnings
28
+ return false if explicitly_allowed?(message)
29
+ return true if disallowed == :all
30
+ disallowed.any? do |rule|
31
+ case rule
32
+ when String, Symbol
33
+ message.include?(rule.to_s)
34
+ when Regexp
35
+ rule.match?(message)
36
+ end
37
+ end
38
+ end
39
+
40
+ def explicitly_allowed?(message)
41
+ allowances = @explicitly_allowed_warnings.value
42
+ return false unless allowances
43
+ return true if allowances == :all
44
+ allowances = [allowances] unless allowances.kind_of?(Array)
45
+ allowances.any? do |rule|
46
+ case rule
47
+ when String, Symbol
48
+ message.include?(rule.to_s)
49
+ when Regexp
50
+ rule.match?(message)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/kernel/singleton_class"
4
3
  require "active_support/core_ext/module/delegation"
5
4
 
6
5
  module ActiveSupport
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/module/aliasing"
4
3
  require "active_support/core_ext/array/extract_options"
4
+ require "active_support/core_ext/module/redefine_method"
5
5
 
6
6
  module ActiveSupport
7
7
  class Deprecation
@@ -53,37 +53,32 @@ module ActiveSupport
53
53
  options = method_names.extract_options!
54
54
  deprecator = options.delete(:deprecator) || self
55
55
  method_names += options.keys
56
- mod = Module.new
56
+ mod = nil
57
57
 
58
58
  method_names.each do |method_name|
59
+ message = options[method_name]
59
60
  if target_module.method_defined?(method_name) || target_module.private_method_defined?(method_name)
60
- aliased_method, punctuation = method_name.to_s.sub(/([?!=])$/, ""), $1
61
- with_method = "#{aliased_method}_with_deprecation#{punctuation}"
62
- without_method = "#{aliased_method}_without_deprecation#{punctuation}"
63
-
64
- target_module.send(:define_method, with_method) do |*args, &block|
65
- deprecator.deprecation_warning(method_name, options[method_name])
66
- send(without_method, *args, &block)
67
- end
68
-
69
- target_module.send(:alias_method, without_method, method_name)
70
- target_module.send(:alias_method, method_name, with_method)
71
-
72
- case
73
- when target_module.protected_method_defined?(without_method)
74
- target_module.send(:protected, method_name)
75
- when target_module.private_method_defined?(without_method)
76
- target_module.send(:private, method_name)
61
+ method = target_module.instance_method(method_name)
62
+ target_module.module_eval do
63
+ redefine_method(method_name) do |*args, &block|
64
+ deprecator.deprecation_warning(method_name, message)
65
+ method.bind(self).call(*args, &block)
66
+ end
67
+ ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
77
68
  end
78
69
  else
79
- mod.send(:define_method, method_name) do |*args, &block|
80
- deprecator.deprecation_warning(method_name, options[method_name])
81
- super(*args, &block)
70
+ mod ||= Module.new
71
+ mod.module_eval do
72
+ define_method(method_name) do |*args, &block|
73
+ deprecator.deprecation_warning(method_name, message)
74
+ super(*args, &block)
75
+ end
76
+ ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
82
77
  end
83
78
  end
84
79
  end
85
80
 
86
- target_module.prepend(mod) unless mod.instance_methods(false).empty?
81
+ target_module.prepend(mod) if mod
87
82
  end
88
83
  end
89
84
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/regexp"
4
-
5
3
  module ActiveSupport
6
4
  class Deprecation
7
5
  class DeprecationProxy #:nodoc:
@@ -122,9 +120,16 @@ module ActiveSupport
122
120
  # # => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead.
123
121
  # (Backtrace information…)
124
122
  # ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
125
- class DeprecatedConstantProxy < DeprecationProxy
123
+ class DeprecatedConstantProxy < Module
124
+ def self.new(*args, **options, &block)
125
+ object = args.first
126
+
127
+ return object unless object
128
+ super
129
+ end
130
+
126
131
  def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance, message: "#{old_const} is deprecated! Use #{new_const} instead.")
127
- require "active_support/inflector/methods"
132
+ Kernel.require "active_support/inflector/methods"
128
133
 
129
134
  @old_const = old_const
130
135
  @new_const = new_const
@@ -132,6 +137,18 @@ module ActiveSupport
132
137
  @message = message
133
138
  end
134
139
 
140
+ instance_methods.each { |m| undef_method m unless /^__|^object_id$/.match?(m) }
141
+
142
+ # Don't give a deprecation warning on inspect since test/unit and error
143
+ # logs rely on it for diagnostics.
144
+ def inspect
145
+ target.inspect
146
+ end
147
+
148
+ # Don't give a deprecation warning on methods that IRB may invoke
149
+ # during tab-completion.
150
+ delegate :hash, :instance_methods, :name, :respond_to?, to: :target
151
+
135
152
  # Returns the class of the new constant.
136
153
  #
137
154
  # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
@@ -146,8 +163,14 @@ module ActiveSupport
146
163
  ActiveSupport::Inflector.constantize(@new_const.to_s)
147
164
  end
148
165
 
149
- def warn(callstack, called, args)
150
- @deprecator.warn(@message, callstack)
166
+ def const_missing(name)
167
+ @deprecator.warn(@message, caller_locations)
168
+ target.const_get(name)
169
+ end
170
+
171
+ def method_missing(called, *args, &block)
172
+ @deprecator.warn(@message, caller_locations)
173
+ target.__send__(called, *args, &block)
151
174
  end
152
175
  end
153
176
  end
@@ -6,7 +6,7 @@ module ActiveSupport
6
6
  class Deprecation
7
7
  module Reporting
8
8
  # Whether to print a message (silent mode)
9
- attr_accessor :silenced
9
+ attr_writer :silenced
10
10
  # Name of gem where method is deprecated
11
11
  attr_accessor :gem_name
12
12
 
@@ -20,7 +20,11 @@ module ActiveSupport
20
20
 
21
21
  callstack ||= caller_locations(2)
22
22
  deprecation_message(callstack, message).tap do |m|
23
- behavior.each { |b| b.call(m, callstack, deprecation_horizon, gem_name) }
23
+ if deprecation_disallowed?(message)
24
+ disallowed_behavior.each { |b| b.call(m, callstack, deprecation_horizon, gem_name) }
25
+ else
26
+ behavior.each { |b| b.call(m, callstack, deprecation_horizon, gem_name) }
27
+ end
24
28
  end
25
29
  end
26
30
 
@@ -33,11 +37,50 @@ module ActiveSupport
33
37
  # ActiveSupport::Deprecation.warn('something broke!')
34
38
  # end
35
39
  # # => nil
36
- def silence
37
- old_silenced, @silenced = @silenced, true
38
- yield
39
- ensure
40
- @silenced = old_silenced
40
+ def silence(&block)
41
+ @silenced_thread.bind(true, &block)
42
+ end
43
+
44
+ # Allow previously disallowed deprecation warnings within the block.
45
+ # <tt>allowed_warnings</tt> can be an array containing strings, symbols, or regular
46
+ # expressions. (Symbols are treated as strings). These are compared against
47
+ # the text of deprecation warning messages generated within the block.
48
+ # Matching warnings will be exempt from the rules set by
49
+ # +ActiveSupport::Deprecation.disallowed_warnings+
50
+ #
51
+ # The optional <tt>if:</tt> argument accepts a truthy/falsy value or an object that
52
+ # responds to <tt>.call</tt>. If truthy, then matching warnings will be allowed.
53
+ # If falsey then the method yields to the block without allowing the warning.
54
+ #
55
+ # ActiveSupport::Deprecation.disallowed_behavior = :raise
56
+ # ActiveSupport::Deprecation.disallowed_warnings = [
57
+ # "something broke"
58
+ # ]
59
+ #
60
+ # ActiveSupport::Deprecation.warn('something broke!')
61
+ # # => ActiveSupport::DeprecationException
62
+ #
63
+ # ActiveSupport::Deprecation.allow ['something broke'] do
64
+ # ActiveSupport::Deprecation.warn('something broke!')
65
+ # end
66
+ # # => nil
67
+ #
68
+ # ActiveSupport::Deprecation.allow ['something broke'], if: Rails.env.production? do
69
+ # ActiveSupport::Deprecation.warn('something broke!')
70
+ # end
71
+ # # => ActiveSupport::DeprecationException for dev/test, nil for production
72
+ def allow(allowed_warnings = :all, if: true, &block)
73
+ conditional = binding.local_variable_get(:if)
74
+ conditional = conditional.call if conditional.respond_to?(:call)
75
+ if conditional
76
+ @explicitly_allowed_warnings.bind(allowed_warnings, &block)
77
+ else
78
+ yield
79
+ end
80
+ end
81
+
82
+ def silenced
83
+ @silenced || @silenced_thread.value
41
84
  end
42
85
 
43
86
  def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)