Warn for calling public/protected/private/module_function without arguments inside method

Calling these methods without an argument does not have the
desired effect inside a method.

Fixes [Bug #13249]
This commit is contained in:
Jeremy Evans 2019-08-24 17:11:06 -07:00
Родитель db84123600
Коммит 2993b24a1e
3 изменённых файлов: 67 добавлений и 1 удалений

Просмотреть файл

@ -131,6 +131,48 @@ class TestClass < Test::Unit::TestCase
[:module_function, :extend_object, :append_features, :prepend_features])
end
def test_visibility_inside_method
assert_warn(/calling private without arguments inside a method may not have the intended effect/, '[ruby-core:79751]') do
Class.new do
def self.foo
private
end
foo
end
end
assert_warn(/calling protected without arguments inside a method may not have the intended effect/, '[ruby-core:79751]') do
Class.new do
def self.foo
protected
end
foo
end
end
assert_warn(/calling public without arguments inside a method may not have the intended effect/, '[ruby-core:79751]') do
Class.new do
def self.foo
public
end
foo
end
end
assert_warn(/calling private without arguments inside a method may not have the intended effect/, '[ruby-core:79751]') do
Class.new do
class << self
alias priv private
end
def self.foo
priv
end
foo
end
end
end
def test_method_redefinition
feature2155 = '[ruby-dev:39400]'

Просмотреть файл

@ -1394,6 +1394,17 @@ class TestModule < Test::Unit::TestCase
assert_match(/: warning: previous definition of foo/, stderr)
end
def test_module_function_inside_method
assert_warn(/calling module_function without arguments inside a method may not have the intended effect/, '[ruby-core:79751]') do
Module.new do
def self.foo
module_function
end
foo
end
end
end
def test_protected_singleton_method
klass = Class.new
x = klass.new

Просмотреть файл

@ -1126,9 +1126,21 @@ rb_scope_visibility_set(rb_method_visibility_t visi)
vm_cref_set_visibility(visi, FALSE);
}
static void
scope_visibility_check(void)
{
/* Check for public/protected/private/module_function called inside a method */
rb_control_frame_t *cfp = rb_current_execution_context()->cfp+1;
if (cfp && cfp->iseq && cfp->iseq->body->type == ISEQ_TYPE_METHOD) {
rb_warn("calling %s without arguments inside a method may not have the intended effect",
rb_id2name(rb_frame_this_func()));
}
}
static void
rb_scope_module_func_set(void)
{
scope_visibility_check();
vm_cref_set_visibility(METHOD_VISI_PRIVATE, TRUE);
}
@ -1663,7 +1675,8 @@ static VALUE
set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t visi)
{
if (argc == 0) {
rb_scope_visibility_set(visi);
scope_visibility_check();
rb_scope_visibility_set(visi);
}
else {
set_method_visibility(module, argc, argv, visi);