Commit fccd2d4c authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #401 from masamitsu-murase/modify_class_inheritance

Modify class inheritance
parents 622b3f01 b71063b2
...@@ -187,30 +187,39 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) ...@@ -187,30 +187,39 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
struct RClass* struct RClass*
mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id) mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
{ {
struct RClass *c = 0; struct RClass *c, *s;
if (mrb_const_defined(mrb, outer, id)) { if (mrb_const_defined(mrb, outer, id)) {
mrb_value v = mrb_const_get(mrb, outer, id); mrb_value v = mrb_const_get(mrb, outer, id);
mrb_check_type(mrb, v, MRB_TT_CLASS);
c = mrb_class_ptr(v); c = mrb_class_ptr(v);
if (!mrb_nil_p(super) && (c->tt != MRB_TT_CLASS || c->super != mrb_class_ptr(super))) { if (!mrb_nil_p(super)) {
c = 0; if (mrb_type(super) != MRB_TT_CLASS) {
mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
}
if (!c->super || mrb_class_ptr(super) != mrb_class_real(c->super)) {
mrb_raise(mrb, E_TYPE_ERROR, "superclass mismatch for class %s", mrb_sym2name(mrb, id));
}
} }
return c;
} }
if (!c) {
struct RClass *s = 0;
if (!mrb_nil_p(super)) { if (!mrb_nil_p(super)) {
mrb_check_type(mrb, super, MRB_TT_CLASS); if (mrb_type(super) != MRB_TT_CLASS) {
s = mrb_class_ptr(super); mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super));
}
if (!s) {
s = mrb->object_class;
} }
c = mrb_class_new(mrb, s); s = mrb_class_ptr(super);
setup_class(mrb, outer, c, id);
mrb_funcall(mrb, mrb_obj_value(s), "inherited", 1, mrb_obj_value(c));
} }
else {
s = mrb->object_class;
}
c = mrb_class_new(mrb, s);
setup_class(mrb, outer, c, id);
mrb_funcall(mrb, mrb_obj_value(s), "inherited", 1, mrb_obj_value(c));
return c; return c;
} }
......
...@@ -47,36 +47,82 @@ end ...@@ -47,36 +47,82 @@ end
# Not ISO specified # Not ISO specified
assert('Class 1') do assert('Class 1') do
class C; end class C1; end
C.class == Class C1.class == Class
end end
assert('Class 2') do assert('Class 2') do
class C; end class C2; end
C.new.class == C C2.new.class == C2
end end
assert('Class 3') do assert('Class 3') do
class C; end class C3; end
C.new.class.class == Class C3.new.class.class == Class
end end
assert('Class 4') do assert('Class 4') do
class A; end class C4_A; end
class C < A; end class C4 < C4_A; end
C.class == Class C4.class == Class
end end
assert('Class 5') do assert('Class 5') do
class A; end class C5_A; end
class C < A; end class C5 < C5_A; end
C.new.class == C C5.new.class == C5
end end
assert('Class 6') do assert('Class 6') do
class A; end class C6_A; end
class C < A; end class C6 < C6_A; end
C.new.class.class == Class C6.new.class.class == Class
end
assert('Class 7') do
class C7_A; end
class C7_B; end
class C7 < C7_A; end
error = false
begin
# Different superclass.
class C7 < C7_B; end
rescue TypeError
error = true
end
error
end
assert('Class 8') do
class C8_A; end
class C8; end # superclass is Object
error = false
begin
# Different superclass.
class C8 < C8_A; end
rescue TypeError
error = true
end
error
end
assert('Class 9') do
Class9Const = "a"
error = false
begin
class Class9Const; end
rescue TypeError
error = true
end
error
end end
assert('Class Module 1') do assert('Class Module 1') 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