-
Notifications
You must be signed in to change notification settings - Fork 21.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
204 additions
and
185 deletions.
There are no files selected for viewing
9 changes: 9 additions & 0 deletions
9
activesupport/lib/active_support/core_ext/module/deprecation.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class Module | ||
# Declare that a method has been deprecated. | ||
# deprecate :foo | ||
# deprecate :bar => 'message' | ||
# deprecate :foo, :bar, :baz => 'warning!', :qux => 'gone!' | ||
def deprecate(*method_names) | ||
ActiveSupport::Deprecation.deprecate_methods(self, *method_names) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,194 +1,18 @@ | ||
require 'yaml' | ||
require 'active_support/deprecation/behaviors' | ||
require 'active_support/deprecation/reporting' | ||
require 'active_support/deprecation/method_wrappers' | ||
require 'active_support/deprecation/proxy_wrappers' | ||
|
||
module ActiveSupport | ||
module Deprecation #:nodoc: | ||
mattr_accessor :debug | ||
self.debug = false | ||
|
||
# Choose the default warn behavior according to RAILS_ENV. | ||
# Ignore deprecation warnings in production. | ||
DEFAULT_BEHAVIORS = { | ||
'test' => Proc.new { |message, callstack| | ||
$stderr.puts(message) | ||
$stderr.puts callstack.join("\n ") if debug | ||
}, | ||
'development' => Proc.new { |message, callstack| | ||
logger = defined?(Rails) ? Rails.logger : Logger.new($stderr) | ||
logger.warn message | ||
logger.debug callstack.join("\n ") if debug | ||
} | ||
} | ||
|
||
class << self | ||
def warn(message = nil, callstack = caller) | ||
behavior.call(deprecation_message(callstack, message), callstack) if behavior && !silenced? | ||
end | ||
|
||
def default_behavior | ||
if defined?(RAILS_ENV) | ||
DEFAULT_BEHAVIORS[RAILS_ENV.to_s] | ||
else | ||
DEFAULT_BEHAVIORS['test'] | ||
end | ||
end | ||
|
||
# Have deprecations been silenced? | ||
def silenced? | ||
@silenced = false unless defined?(@silenced) | ||
@silenced | ||
end | ||
|
||
# Silence deprecation warnings within the block. | ||
def silence | ||
old_silenced, @silenced = @silenced, true | ||
yield | ||
ensure | ||
@silenced = old_silenced | ||
end | ||
|
||
attr_writer :silenced | ||
|
||
|
||
private | ||
def deprecation_message(callstack, message = nil) | ||
message ||= "You are using deprecated behavior which will be removed from the next major or minor release." | ||
"DEPRECATION WARNING: #{message}. #{deprecation_caller_message(callstack)}" | ||
end | ||
|
||
def deprecation_caller_message(callstack) | ||
file, line, method = extract_callstack(callstack) | ||
if file | ||
if line && method | ||
"(called from #{method} at #{file}:#{line})" | ||
else | ||
"(called from #{file}:#{line})" | ||
end | ||
end | ||
end | ||
|
||
def extract_callstack(callstack) | ||
if md = callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/) | ||
md.captures | ||
else | ||
callstack.first | ||
end | ||
end | ||
# The version the deprecated behavior will be removed, by default. | ||
attr_accessor :deprecation_horizon | ||
end | ||
self.deprecation_horizon = '3.0' | ||
|
||
# Behavior is a block that takes a message argument. | ||
mattr_accessor :behavior | ||
self.behavior = default_behavior | ||
|
||
# Warnings are not silenced by default. | ||
# By default, warnings are not silenced and debugging is off. | ||
self.silenced = false | ||
|
||
module ClassMethods #:nodoc: | ||
# Declare that a method has been deprecated. | ||
def deprecate(*method_names) | ||
options = method_names.extract_options! | ||
method_names = method_names + options.keys | ||
method_names.each do |method_name| | ||
alias_method_chain(method_name, :deprecation) do |target, punctuation| | ||
class_eval(<<-EOS, __FILE__, __LINE__) | ||
def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block) | ||
::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn( | ||
self.class.deprecated_method_warning( # self.class.deprecated_method_warning( | ||
:#{method_name}, # :generate_secret, | ||
#{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"), | ||
caller # caller | ||
) # ) | ||
#{target}_without_deprecation#{punctuation}(*args, &block) # generate_secret_without_deprecation(*args, &block) | ||
end # end | ||
EOS | ||
end | ||
end | ||
end | ||
|
||
def deprecated_method_warning(method_name, message=nil) | ||
warning = "#{method_name} is deprecated and will be removed from Rails #{deprecation_horizon}" | ||
case message | ||
when Symbol then "#{warning} (use #{message} instead)" | ||
when String then "#{warning} (#{message})" | ||
else warning | ||
end | ||
end | ||
|
||
def deprecation_horizon | ||
'2.3' | ||
end | ||
end | ||
|
||
class DeprecationProxy #:nodoc: | ||
instance_methods.each { |m| undef_method m unless m =~ /^__/ } | ||
|
||
# Don't give a deprecation warning on inspect since test/unit and error | ||
# logs rely on it for diagnostics. | ||
def inspect | ||
target.inspect | ||
end | ||
|
||
private | ||
def method_missing(called, *args, &block) | ||
warn caller, called, args | ||
target.__send__(called, *args, &block) | ||
end | ||
end | ||
|
||
class DeprecatedObjectProxy < DeprecationProxy | ||
def initialize(object, message) | ||
@object = object | ||
@message = message | ||
end | ||
|
||
private | ||
def target | ||
@object | ||
end | ||
|
||
def warn(callstack, called, args) | ||
ActiveSupport::Deprecation.warn(@message, callstack) | ||
end | ||
end | ||
|
||
# Stand-in for <tt>@request</tt>, <tt>@attributes</tt>, <tt>@params</tt>, etc. | ||
# which emits deprecation warnings on any method call (except +inspect+). | ||
class DeprecatedInstanceVariableProxy < DeprecationProxy #:nodoc: | ||
def initialize(instance, method, var = "@#{method}") | ||
@instance, @method, @var = instance, method, var | ||
end | ||
|
||
private | ||
def target | ||
@instance.__send__(@method) | ||
end | ||
|
||
def warn(callstack, called, args) | ||
ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack) | ||
end | ||
end | ||
|
||
class DeprecatedConstantProxy < DeprecationProxy #:nodoc: | ||
def initialize(old_const, new_const) | ||
@old_const = old_const | ||
@new_const = new_const | ||
end | ||
|
||
def class | ||
target.class | ||
end | ||
|
||
private | ||
def target | ||
@new_const.to_s.constantize | ||
end | ||
|
||
def warn(callstack, called, args) | ||
ActiveSupport::Deprecation.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack) | ||
end | ||
end | ||
self.debug = false | ||
end | ||
end | ||
|
||
class Module | ||
include ActiveSupport::Deprecation::ClassMethods | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module ActiveSupport | ||
module Deprecation | ||
class << self | ||
# Behavior is a block that takes a message argument. | ||
attr_writer :behavior | ||
|
||
# Whether to print a backtrace along with the warning. | ||
attr_accessor :debug | ||
|
||
def behavior | ||
@behavior ||= default_behavior | ||
end | ||
|
||
def default_behavior | ||
Deprecation::DEFAULT_BEHAVIORS[defined?(Rails) ? Rails.env.to_s : 'test'] | ||
end | ||
end | ||
|
||
# Default warning behaviors per Rails.env. Ignored in production. | ||
DEFAULT_BEHAVIORS = { | ||
'test' => Proc.new { |message, callstack| | ||
$stderr.puts(message) | ||
$stderr.puts callstack.join("\n ") if debug | ||
}, | ||
'development' => Proc.new { |message, callstack| | ||
logger = defined?(Rails) ? Rails.logger : Logger.new($stderr) | ||
logger.warn message | ||
logger.debug callstack.join("\n ") if debug | ||
} | ||
} | ||
end | ||
end |
27 changes: 27 additions & 0 deletions
27
activesupport/lib/active_support/deprecation/method_wrappers.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
require 'active_support/core_ext/module/deprecation' | ||
|
||
module ActiveSupport | ||
class << Deprecation | ||
# Declare that a method has been deprecated. | ||
def deprecate_methods(target_module, *method_names) | ||
options = method_names.extract_options! | ||
method_names += options.keys | ||
|
||
method_names.each do |method_name| | ||
target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation| | ||
target_module.module_eval(<<-end_eval, __FILE__, __LINE__) | ||
def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block) | ||
::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn( | ||
::ActiveSupport::Deprecation.deprecated_method_warning( # ::ActiveSupport::Deprecation.deprecated_method_warning( | ||
:#{method_name}, # :generate_secret, | ||
#{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"), | ||
caller # caller | ||
) # ) | ||
#{target}_without_deprecation#{punctuation}(*args, &block) # generate_secret_without_deprecation(*args, &block) | ||
end # end | ||
end_eval | ||
end | ||
end | ||
end | ||
end | ||
end |
72 changes: 72 additions & 0 deletions
72
activesupport/lib/active_support/deprecation/proxy_wrappers.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
module ActiveSupport | ||
module Deprecation | ||
class DeprecationProxy #:nodoc: | ||
instance_methods.each { |m| undef_method m unless m =~ /^__/ } | ||
|
||
# Don't give a deprecation warning on inspect since test/unit and error | ||
# logs rely on it for diagnostics. | ||
def inspect | ||
target.inspect | ||
end | ||
|
||
private | ||
def method_missing(called, *args, &block) | ||
warn caller, called, args | ||
target.__send__(called, *args, &block) | ||
end | ||
end | ||
|
||
class DeprecatedObjectProxy < DeprecationProxy #:nodoc: | ||
def initialize(object, message) | ||
@object = object | ||
@message = message | ||
end | ||
|
||
private | ||
def target | ||
@object | ||
end | ||
|
||
def warn(callstack, called, args) | ||
ActiveSupport::Deprecation.warn(@message, callstack) | ||
end | ||
end | ||
|
||
# Stand-in for <tt>@request</tt>, <tt>@attributes</tt>, <tt>@params</tt>, etc. | ||
# which emits deprecation warnings on any method call (except +inspect+). | ||
class DeprecatedInstanceVariableProxy < DeprecationProxy #:nodoc: | ||
def initialize(instance, method, var = "@#{method}") | ||
@instance, @method, @var = instance, method, var | ||
end | ||
|
||
private | ||
def target | ||
@instance.__send__(@method) | ||
end | ||
|
||
def warn(callstack, called, args) | ||
ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack) | ||
end | ||
end | ||
|
||
class DeprecatedConstantProxy < DeprecationProxy #:nodoc: | ||
def initialize(old_const, new_const) | ||
@old_const = old_const | ||
@new_const = new_const | ||
end | ||
|
||
def class | ||
target.class | ||
end | ||
|
||
private | ||
def target | ||
@new_const.to_s.constantize | ||
end | ||
|
||
def warn(callstack, called, args) | ||
ActiveSupport::Deprecation.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack) | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.