let autoloaded? support modules with overridden names [closes #36757]
This commit is contained in:
parent
7f21e04e61
commit
59c6d29ffa
@ -20,6 +20,9 @@ module ActiveSupport #:nodoc:
|
||||
module Dependencies #:nodoc:
|
||||
extend self
|
||||
|
||||
UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
|
||||
private_constant :UNBOUND_METHOD_MODULE_NAME
|
||||
|
||||
mattr_accessor :interlock, default: Interlock.new
|
||||
|
||||
# :doc:
|
||||
@ -658,7 +661,7 @@ def safe_constantize(name)
|
||||
|
||||
# Determine if the given constant has been automatically loaded.
|
||||
def autoloaded?(desc)
|
||||
return false if desc.is_a?(Module) && desc.anonymous?
|
||||
return false if desc.is_a?(Module) && real_mod_name(desc).nil?
|
||||
name = to_constant_name desc
|
||||
return false unless qualified_const_defined?(name)
|
||||
autoloaded_constants.include?(name)
|
||||
@ -714,7 +717,7 @@ def to_constant_name(desc) #:nodoc:
|
||||
when String then desc.sub(/^::/, "")
|
||||
when Symbol then desc.to_s
|
||||
when Module
|
||||
desc.name ||
|
||||
real_mod_name(desc) ||
|
||||
raise(ArgumentError, "Anonymous modules have no name to be referenced by")
|
||||
else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
|
||||
end
|
||||
@ -788,6 +791,14 @@ def remove_constant(const) #:nodoc:
|
||||
def log(message)
|
||||
logger.debug("autoloading: #{message}") if logger && verbose
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Returns the original name of a class or module even if `name` has been
|
||||
# overridden.
|
||||
def real_mod_name(mod)
|
||||
UNBOUND_METHOD_MODULE_NAME.bind(mod).call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -28,7 +28,7 @@ def autoloaded_constants
|
||||
end
|
||||
|
||||
def autoloaded?(object)
|
||||
cpath = object.is_a?(Module) ? object.name : object.to_s
|
||||
cpath = object.is_a?(Module) ? real_mod_name(object) : object.to_s
|
||||
Rails.autoloaders.main.unloadable_cpath?(cpath)
|
||||
end
|
||||
|
||||
|
@ -592,6 +592,13 @@ def test_autoloaded?
|
||||
nil_name = Module.new
|
||||
def nil_name.name() nil end
|
||||
assert_not ActiveSupport::Dependencies.autoloaded?(nil_name)
|
||||
|
||||
invalid_constant_name = Module.new do
|
||||
def self.name
|
||||
"primary::SchemaMigration"
|
||||
end
|
||||
end
|
||||
assert_not ActiveSupport::Dependencies.autoloaded?(invalid_constant_name)
|
||||
end
|
||||
ensure
|
||||
remove_constants(:ModuleFolder)
|
||||
|
@ -98,6 +98,15 @@ class RESTfulController < ApplicationController
|
||||
assert_nil deps.safe_constantize("Admin")
|
||||
end
|
||||
|
||||
test "autoloaded? and overridden class names" do
|
||||
invalid_constant_name = Module.new do
|
||||
def self.name
|
||||
"primary::SchemaMigration"
|
||||
end
|
||||
end
|
||||
assert_not deps.autoloaded?(invalid_constant_name)
|
||||
end
|
||||
|
||||
test "unloadable constants (main)" do
|
||||
app_file "app/models/user.rb", "class User; end"
|
||||
app_file "app/models/post.rb", "class Post; end"
|
||||
|
Loading…
Reference in New Issue
Block a user