mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Do not lose existing constant visibility when autoloading
This copies the private/deprecate constant visibility across the autoload. It still is backwards compatible with setting the private/deprecate constant visibility in the autoloaded file. However, if you explicitly set public constant in the autoloaded file, that will be reset after the autoload. Fixes [Bug #11055]
This commit is contained in:
parent
b96d559c69
commit
47c97e1e84
Notes:
git
2019-12-04 00:32:12 +09:00
2 changed files with 69 additions and 0 deletions
|
@ -295,6 +295,66 @@ p Foo::Bar
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_autoload_private_constant_before_autoload
|
||||||
|
Dir.mktmpdir('autoload') do |tmpdir|
|
||||||
|
File.write(tmpdir+"/zzz.rb", "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
class AutoloadTest
|
||||||
|
ZZZ = :ZZZ
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
|
bug = '[Bug #11055]'
|
||||||
|
begin;
|
||||||
|
class AutoloadTest
|
||||||
|
autoload :ZZZ, "zzz.rb"
|
||||||
|
private_constant :ZZZ
|
||||||
|
ZZZ
|
||||||
|
end
|
||||||
|
assert_raise(NameError, bug) {AutoloadTest::ZZZ}
|
||||||
|
end;
|
||||||
|
assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
|
bug = '[Bug #11055]'
|
||||||
|
begin;
|
||||||
|
class AutoloadTest
|
||||||
|
autoload :ZZZ, "zzz.rb"
|
||||||
|
private_constant :ZZZ
|
||||||
|
end
|
||||||
|
assert_raise(NameError, bug) {AutoloadTest::ZZZ}
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_autoload_deprecate_constant_before_autoload
|
||||||
|
Dir.mktmpdir('autoload') do |tmpdir|
|
||||||
|
File.write(tmpdir+"/zzz.rb", "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
class AutoloadTest
|
||||||
|
ZZZ = :ZZZ
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
|
bug = '[Bug #11055]'
|
||||||
|
begin;
|
||||||
|
class AutoloadTest
|
||||||
|
autoload :ZZZ, "zzz.rb"
|
||||||
|
deprecate_constant :ZZZ
|
||||||
|
end
|
||||||
|
assert_warning(/ZZZ is deprecated/, bug) {class AutoloadTest; ZZZ; end}
|
||||||
|
assert_warning(/ZZZ is deprecated/, bug) {AutoloadTest::ZZZ}
|
||||||
|
end;
|
||||||
|
assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
|
bug = '[Bug #11055]'
|
||||||
|
begin;
|
||||||
|
class AutoloadTest
|
||||||
|
autoload :ZZZ, "zzz.rb"
|
||||||
|
deprecate_constant :ZZZ
|
||||||
|
end
|
||||||
|
assert_warning(/ZZZ is deprecated/, bug) {AutoloadTest::ZZZ}
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_autoload_fork
|
def test_autoload_fork
|
||||||
EnvUtil.default_warning do
|
EnvUtil.default_warning do
|
||||||
Tempfile.create(['autoload', '.rb']) {|file|
|
Tempfile.create(['autoload', '.rb']) {|file|
|
||||||
|
|
|
@ -2226,6 +2226,8 @@ rb_autoload_load(VALUE mod, ID id)
|
||||||
struct autoload_data_i *ele;
|
struct autoload_data_i *ele;
|
||||||
struct autoload_const *ac;
|
struct autoload_const *ac;
|
||||||
struct autoload_state state;
|
struct autoload_state state;
|
||||||
|
int flag = -1;
|
||||||
|
rb_const_entry_t *ce;
|
||||||
|
|
||||||
if (!autoload_defined_p(mod, id)) return Qfalse;
|
if (!autoload_defined_p(mod, id)) return Qfalse;
|
||||||
load = check_autoload_required(mod, id, &loading);
|
load = check_autoload_required(mod, id, &loading);
|
||||||
|
@ -2233,6 +2235,10 @@ rb_autoload_load(VALUE mod, ID id)
|
||||||
src = rb_sourcefile();
|
src = rb_sourcefile();
|
||||||
if (src && loading && strcmp(src, loading) == 0) return Qfalse;
|
if (src && loading && strcmp(src, loading) == 0) return Qfalse;
|
||||||
|
|
||||||
|
if ((ce = rb_const_lookup(mod, id))) {
|
||||||
|
flag = ce->flag & (CONST_DEPRECATED | CONST_VISIBILITY_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
/* set ele->state for a marker of autoloading thread */
|
/* set ele->state for a marker of autoloading thread */
|
||||||
if (!(ele = get_autoload_data(load, &ac))) {
|
if (!(ele = get_autoload_data(load, &ac))) {
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
|
@ -2264,6 +2270,9 @@ rb_autoload_load(VALUE mod, ID id)
|
||||||
result = rb_ensure(autoload_require, (VALUE)&state,
|
result = rb_ensure(autoload_require, (VALUE)&state,
|
||||||
autoload_reset, (VALUE)&state);
|
autoload_reset, (VALUE)&state);
|
||||||
|
|
||||||
|
if (flag > 0 && (ce = rb_const_lookup(mod, id))) {
|
||||||
|
ce->flag |= flag;
|
||||||
|
}
|
||||||
RB_GC_GUARD(load);
|
RB_GC_GUARD(load);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue