mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
vm_method.c: fix super in refined module
* vm_method.c (rb_method_entry_complement_defined_class): clone the original method entry of refined module instance method with the active ICLASS, to track super method chain. [ruby-dev:50390] [Bug #14232] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61484 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3802fb92ff
commit
e973bde0d0
2 changed files with 44 additions and 2 deletions
|
@ -2055,6 +2055,25 @@ class TestRefinement < Test::Unit::TestCase
|
|||
INPUT
|
||||
end
|
||||
|
||||
def test_super_from_refined_module
|
||||
a = EnvUtil.labeled_module("A") do
|
||||
def foo;"[A#{super}]";end
|
||||
end
|
||||
b = EnvUtil.labeled_class("B") do
|
||||
def foo;"[B]";end
|
||||
end
|
||||
c = EnvUtil.labeled_class("C", b) do
|
||||
include a
|
||||
def foo;"[C#{super}]";end
|
||||
end
|
||||
d = EnvUtil.labeled_module("D") do
|
||||
refine(a) do
|
||||
def foo;end
|
||||
end
|
||||
end
|
||||
assert_equal("[C[A[B]]]", c.new.foo, '[ruby-dev:50390] [Bug #14232]')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def eval_using(mod, s)
|
||||
|
|
27
vm_method.c
27
vm_method.c
|
@ -404,10 +404,33 @@ rb_method_entry_clone(const rb_method_entry_t *src_me)
|
|||
const rb_callable_method_entry_t *
|
||||
rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
|
||||
{
|
||||
rb_method_entry_t *me = rb_method_entry_alloc(called_id, src_me->owner, defined_class,
|
||||
method_definition_addref_complement(src_me->def));
|
||||
rb_method_definition_t *def = src_me->def;
|
||||
rb_method_entry_t *me;
|
||||
struct {
|
||||
const struct rb_method_entry_struct *orig_me;
|
||||
VALUE owner;
|
||||
} refined = {0};
|
||||
|
||||
if (!src_me->defined_class &&
|
||||
def->type == VM_METHOD_TYPE_REFINED &&
|
||||
def->body.refined.orig_me) {
|
||||
const rb_method_entry_t *orig_me =
|
||||
rb_method_entry_clone(def->body.refined.orig_me);
|
||||
RB_OBJ_WRITE((VALUE)orig_me, &orig_me->defined_class, defined_class);
|
||||
refined.orig_me = orig_me;
|
||||
refined.owner = orig_me->owner;
|
||||
def = NULL;
|
||||
}
|
||||
else {
|
||||
def = method_definition_addref_complement(def);
|
||||
}
|
||||
me = rb_method_entry_alloc(called_id, src_me->owner, defined_class, def);
|
||||
METHOD_ENTRY_FLAGS_COPY(me, src_me);
|
||||
METHOD_ENTRY_COMPLEMENTED_SET(me);
|
||||
if (!def) {
|
||||
def = method_definition_create(VM_METHOD_TYPE_REFINED, called_id);
|
||||
method_definition_set(me, def, &refined);
|
||||
}
|
||||
|
||||
VM_ASSERT(RB_TYPE_P(me->owner, T_MODULE));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue