From 5ed61bcb5a349b44525deae1a6a6c58674926cd3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 27 May 2019 00:54:33 +0200 Subject: [PATCH] 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. --- src/gsi/gsi/gsiClassBase.cc | 14 +++----------- src/gsi/gsi/gsiClassBase.h | 2 +- src/pya/pya/pyaModule.cc | 14 ++++++++------ src/rba/rba/rba.cc | 19 ++++++++++--------- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/gsi/gsi/gsiClassBase.cc b/src/gsi/gsi/gsiClassBase.cc index f8daafecb..aaabee1f6 100644 --- a/src/gsi/gsi/gsiClassBase.cc +++ b/src/gsi/gsi/gsiClassBase.cc @@ -597,17 +597,9 @@ ClassBase::classes_in_definition_order (const char *mod_name) continue; } - bool all_children_available = true; - for (tl::weak_collection::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; } diff --git a/src/gsi/gsi/gsiClassBase.h b/src/gsi/gsi/gsiClassBase.h index 3e8801fc1..f0d508310 100644 --- a/src/gsi/gsi/gsiClassBase.h +++ b/src/gsi/gsi/gsiClassBase.h @@ -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 diff --git a/src/pya/pya/pyaModule.cc b/src/pya/pya/pyaModule.cc index 5cd13d296..51e322471 100644 --- a/src/pya/pya/pyaModule.cc +++ b/src/pya/pya/pyaModule.cc @@ -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::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 ... diff --git a/src/rba/rba/rba.cc b/src/rba/rba/rba.cc index 91795175c..0cbf3faef 100644 --- a/src/rba/rba/rba.cc +++ b/src/rba/rba/rba.cc @@ -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::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