Commit 97c9e6b0 authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

Fix `include`, `prepend` and `extend` to frozen object

parent cf697240
......@@ -1070,8 +1070,8 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru
MRB_API void
mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
{
int changed = include_module_at(mrb, c, find_origin(c), m, 1);
if (changed < 0) {
mrb_check_frozen(mrb, c);
if (include_module_at(mrb, c, find_origin(c), m, 1) < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
}
}
......@@ -1082,6 +1082,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
struct RClass *origin;
int changed = 0;
mrb_check_frozen(mrb, c);
if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c);
origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED;
......
......@@ -240,6 +240,9 @@ assert('Kernel#extend', '15.3.1.3.13') do
assert_true a.respond_to?(:test_method)
assert_false b.respond_to?(:test_method)
assert_raise(FrozenError) { Object.new.freeze.extend(Test4ExtendModule) }
assert_raise(FrozenError, TypeError) { :sym.extend(Test4ExtendModule) }
end
assert('Kernel#extend works on toplevel', '15.3.1.3.13') do
......
......@@ -59,6 +59,7 @@ assert('Module#append_features', '15.2.2.4.10') do
end
assert_equal Test4AppendFeatures2, Test4AppendFeatures2.const_get(:Const4AppendFeatures2)
assert_raise(FrozenError) { Module.new.append_features Class.new.freeze }
end
assert('Module#attr NameError') do
......@@ -275,6 +276,18 @@ assert('Module#const_missing', '15.2.2.4.22') do
assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist)
end
assert('Module#extend_object', '15.2.2.4.25') do
cls = Class.new
mod = Module.new { def foo; end }
a = cls.new
b = cls.new
mod.extend_object(b)
assert_false a.respond_to?(:foo)
assert_true b.respond_to?(:foo)
assert_raise(FrozenError) { mod.extend_object(cls.new.freeze) }
assert_raise(FrozenError, TypeError) { mod.extend_object(1) }
end
assert('Module#include', '15.2.2.4.27') do
module Test4Include
Const4Include = 42
......@@ -288,6 +301,7 @@ assert('Module#include', '15.2.2.4.27') do
assert_equal 42, Test4Include2.const_get(:Const4Include)
assert_equal Test4Include2, Test4Include2.include_result
assert_raise(FrozenError) { Module.new.freeze.include Test4Include }
end
assert('Module#include?', '15.2.2.4.28') do
......@@ -398,6 +412,15 @@ assert('Module#define_method') do
end
end
assert 'Module#prepend_features' do
mod = Module.new { def m; :mod end }
cls = Class.new { def m; :cls end }
assert_equal :cls, cls.new.m
mod.prepend_features(cls)
assert_equal :mod, cls.new.m
assert_raise(FrozenError) { Module.new.prepend_features(Class.new.freeze) }
end
# @!group prepend
assert('Module#prepend') do
module M0
......@@ -632,6 +655,10 @@ end
# end
# end;
#end
assert 'Module#prepend to frozen class' do
assert_raise(FrozenError) { Class.new.freeze.prepend Module.new }
end
# @!endgroup prepend
assert('Module#to_s') do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment