aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorPrem Sichanugrist <s@sikac.hu>2019-06-26 19:33:22 +0900
committerPrem Sichanugrist <s@sikac.hu>2019-07-05 12:38:58 +0900
commit48c0abb4748c30adeecc17058f0220e87bcbe84a (patch)
tree4dacd4c3fc841d2037353aef36ea3733ccb61086 /activesupport
parentfb3ecbf130e141688782bafb7da979bf0ecedf1a (diff)
downloadrails-48c0abb4748c30adeecc17058f0220e87bcbe84a.tar.gz
rails-48c0abb4748c30adeecc17058f0220e87bcbe84a.tar.bz2
rails-48c0abb4748c30adeecc17058f0220e87bcbe84a.zip
Fix problem with accessing constant proxy subclass
This commit fixes #36313. After #32065 moved `SourceAnnotationExtractor` into `Rails` module, it broke the ability to access `SourceAnnotationExtractor::Annotate` directly as user would get this error: TypeError: Rails::SourceAnnotationExtractor is not a class/module This commit fixes the issue by making `DeprecatedConstantProxy` to inherit from `Module` and then defines `method_missing` and `const_missing` to retain the previous functionality. Thank you Matthew Draper for the idea of how to fix the issue! [Prem Sichanugrist & Matthew Draper]
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/deprecation/proxy_wrappers.rb27
-rw-r--r--activesupport/test/deprecation_test.rb17
2 files changed, 41 insertions, 3 deletions
diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
index 56f1e23136..24c75b5661 100644
--- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
+++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb
@@ -120,7 +120,14 @@ module ActiveSupport
# # => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead.
# (Backtrace information…)
# ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
- class DeprecatedConstantProxy < DeprecationProxy
+ class DeprecatedConstantProxy < Module
+ def self.new(*args, &block)
+ object = args.first
+
+ return object unless object
+ super
+ end
+
def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance, message: "#{old_const} is deprecated! Use #{new_const} instead.")
require "active_support/inflector/methods"
@@ -130,6 +137,14 @@ module ActiveSupport
@message = message
end
+ instance_methods.each { |m| undef_method m unless /^__|^object_id$/.match?(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
+
# Returns the class of the new constant.
#
# PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune)
@@ -144,8 +159,14 @@ module ActiveSupport
ActiveSupport::Inflector.constantize(@new_const.to_s)
end
- def warn(callstack, called, args)
- @deprecator.warn(@message, callstack)
+ def const_missing(name)
+ @deprecator.warn(@message, caller_locations)
+ target.const_get(name)
+ end
+
+ def method_missing(called, *args, &block)
+ @deprecator.warn(@message, caller_locations)
+ target.__send__(called, *args, &block)
end
end
end
diff --git a/activesupport/test/deprecation_test.rb b/activesupport/test/deprecation_test.rb
index f25c704586..ae2f4a6e58 100644
--- a/activesupport/test/deprecation_test.rb
+++ b/activesupport/test/deprecation_test.rb
@@ -38,6 +38,11 @@ class Deprecatee
C = 1
end
A = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("Deprecatee::A", "Deprecatee::B::C")
+
+ module New
+ class Descendant; end
+ end
+ Old = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("Deprecatee::Old", "Deprecatee::New")
end
class DeprecateeWithAccessor
@@ -210,6 +215,18 @@ class DeprecationTest < ActiveSupport::TestCase
assert_not_deprecated { assert_equal Deprecatee::B::C.class, Deprecatee::A.class }
end
+ def test_deprecated_constant_descendant
+ assert_not_deprecated { Deprecatee::New::Descendant }
+
+ assert_deprecated("Deprecatee::Old") do
+ assert_equal Deprecatee::Old::Descendant, Deprecatee::New::Descendant
+ end
+
+ assert_raises(NameError) do
+ assert_deprecated("Deprecatee::Old") { Deprecatee::Old::NON_EXISTENCE }
+ end
+ end
+
def test_deprecated_constant_accessor
assert_not_deprecated { DeprecateeWithAccessor::B::C }
assert_deprecated("DeprecateeWithAccessor::A") { assert_equal DeprecateeWithAccessor::B::C, DeprecateeWithAccessor::A }