@@ -7,6 +7,29 @@ module Mongoid
77 #
88 # @api private
99 module Deprecable
10+ # A Mongoid::Deprecation instance to use for reporting deprecations
11+ def deprecator
12+ @deprecator ||= Mongoid ::Deprecation . new
13+ end
14+
15+ # Resets all deprecation warnings. For use in tests.
16+ def reset_deprecation_warnings!
17+ DEPRECATION_WARNING_MUTEX . synchronize { @deprecation_warnings = { } }
18+ end
19+
20+ # Emits a warning using the current deprecator. If the given warning (as
21+ # identified by `id`) has already been issued previously, this is a no-op.
22+ #
23+ # @param [ Symbol ] id The unique identifier for this warning.
24+ # @param [ String ] warning The warning message to emit.
25+ # @param [ Array<Thread::Backtrace::Location> | nil ] callstack The backtrace at the call site.
26+ def deprecation_warning ( id , warning , callstack = nil )
27+ site = callstack &.first
28+ deprecation_warning_guard ( id , site ? "#{ site . path } :#{ site . lineno } " : nil ) do
29+ deprecator . warn ( warning , callstack )
30+ end
31+ end
32+
1033 # Declares method(s) as deprecated.
1134 #
1235 # @example Deprecate a method.
@@ -25,8 +48,28 @@ module Deprecable
2548 # @param [ [ Symbol | Hash<Symbol, [ Symbol | String ]> ]... ] *method_descriptors
2649 # The methods to deprecate, with optional replacement instructions.
2750 def deprecate ( target_module , *method_descriptors )
28- @_deprecator ||= Mongoid ::Deprecation . new
29- @_deprecator . deprecate_methods ( target_module , *method_descriptors )
51+ deprecator . deprecate_methods ( target_module , *method_descriptors )
52+ end
53+
54+ private
55+
56+ # The Mutex instance used to guard the deprecation warning flags.
57+ DEPRECATION_WARNING_MUTEX = Mutex . new
58+
59+ # Wraps access to the warnings Hash in a synchronize block. If the given
60+ # id+callsite has not been warned already, the method will yield to a block and then
61+ # flag the id. Otherwise, it returns immediately.
62+ def deprecation_warning_guard ( id , callsite )
63+ DEPRECATION_WARNING_MUTEX . synchronize do
64+ @deprecation_warnings ||= { }
65+
66+ key = "#{ id } :#{ callsite } "
67+ return if @deprecation_warnings . key? ( key )
68+
69+ yield
70+
71+ @deprecation_warnings [ key ] = true
72+ end
3073 end
3174 end
3275end
0 commit comments