RBA/pya: don't inject child classes into module

Previously, child classes have also appeared in
the module. Now, they only appear in the parent
class.
This commit is contained in:
Matthias Koefferlein 2019-05-27 00:54:33 +02:00
parent 4858f3418a
commit 5ed61bcb5a
4 changed files with 22 additions and 27 deletions

View File

@ -597,17 +597,9 @@ ClassBase::classes_in_definition_order (const char *mod_name)
continue;
}
bool all_children_available = true;
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = (*c)->begin_child_classes (); cc != (*c)->end_child_classes (); ++cc) {
tl_assert (cc->declaration () != 0);
if (taken.find (cc.operator-> ()) == taken.end ()) {
reason_for_more = tl::sprintf ("child of class %s.%s not available (%s.%s)", (*c)->module (), (*c)->name (), cc->module (), cc->name ());
all_children_available = false;
break;
}
}
if (! all_children_available) {
// can't produce this class yet - the children are not available yet.
if ((*c)->parent () != 0 && taken.find ((*c)->parent ()) == taken.end ()) {
// can't produce this class yet - it's a child of a parent that is not produced yet.
reason_for_more = tl::sprintf ("parent of class %s.%s not available (%s.%s)", (*c)->module (), (*c)->name (), (*c)->parent ()->module (), (*c)->parent ()->name ());
more_classes.push_back (*c);
continue;
}

View File

@ -249,7 +249,7 @@ public:
* Definition order is:
* - No duplicate class entries
* - Base classes before their derived classes
* - Child classes before their parent classes
* - Child classes after their parent classes
*
* If a module name is given, only top-level classes from this
* module will be considered. However, the list may also include

View File

@ -2427,14 +2427,16 @@ PythonModule::make_classes (const char *mod_name)
tl_assert (cls_for_type (type) == *c);
PyList_Append (all_list.get (), PythonRef (c2python ((*c)->name ())).get ());
PyModule_AddObject (module, (*c)->name ().c_str (), (PyObject *) type);
// Create the sub-class attributes
// Add to the parent class as child class or add to module
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = (*c)->begin_child_classes (); cc != (*c)->end_child_classes (); ++cc) {
tl_assert (cc->declaration () != 0);
PythonRef cc_obj ((PyObject *) PythonClassClientData::py_type (*cc->declaration ()), false);
set_type_attr (type, cc->name ().c_str (), cc_obj);
if ((*c)->parent ()) {
tl_assert ((*c)->parent ()->declaration () != 0);
PyTypeObject *parent_type = PythonClassClientData::py_type (*(*c)->parent ()->declaration ());
PythonRef attr ((PyObject *) type);
set_type_attr (parent_type, (*c)->name ().c_str (), attr);
} else {
PyModule_AddObject (module, (*c)->name ().c_str (), (PyObject *) type);
}
// Build the attributes now ...

View File

@ -1476,7 +1476,15 @@ rba_init (RubyInterpreterPrivateData *d)
// there should be only main declarations since we merged
tl_assert ((*c)->declaration () == *c);
VALUE klass = rb_define_class_under (module, (*c)->name ().c_str (), super);
VALUE klass;
if ((*c)->parent ()) {
tl_assert (is_registered ((*c)->parent ()));
VALUE parent_class = ruby_cls ((*c)->parent ());
klass = rb_define_class_under (parent_class, (*c)->name ().c_str (), super);
} else {
klass = rb_define_class_under (module, (*c)->name ().c_str (), super);
}
register_class (klass, *c);
rb_define_alloc_func (klass, alloc_proxy);
@ -1612,7 +1620,7 @@ rba_init (RubyInterpreterPrivateData *d)
// x = object with signal "signal"
// x.signal = proc
// this will basically map to
// x.signal(proc)
// x.signal(proc)
// which will make proc the only receiver for the signal
rb_define_alias (klass, (mt->name (mid) + "=").c_str (), mt->name (mid).c_str ());
}
@ -1628,13 +1636,6 @@ rba_init (RubyInterpreterPrivateData *d)
}
// produce the child classes as constants
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = (*c)->begin_child_classes (); cc != (*c)->end_child_classes (); ++cc) {
tl_assert (is_registered (cc.operator-> ()));
rb_define_const (ruby_cls (*c), cc->name ().c_str (), ruby_cls (cc->declaration ()));
}
}
// now make the constants