From 419ed7dd78e8c04db7bf335d7357a8e72aa032df Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 27 May 2019 18:44:42 +0200 Subject: [PATCH] Bugfixed the pya and RBA GSI initialization after last refactoring. --- src/gsi/gsi/gsiClassBase.cc | 8 ++++++++ src/pya/pya/pyaModule.cc | 17 +++++++++++++---- src/rba/rba/rba.cc | 16 +++++++++++----- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/gsi/gsi/gsiClassBase.cc b/src/gsi/gsi/gsiClassBase.cc index aaabee1f6..0ae26c811 100644 --- a/src/gsi/gsi/gsiClassBase.cc +++ b/src/gsi/gsi/gsiClassBase.cc @@ -597,6 +597,14 @@ ClassBase::classes_in_definition_order (const char *mod_name) continue; } + if ((*c)->declaration () != *c && taken.find ((*c)->declaration ()) == taken.end ()) { + // can't produce this class yet - it's a child of a parent that is not produced yet. + tl_assert ((*c)->declaration () != 0); + reason_for_more = tl::sprintf ("class %s.%s refers to another class (%s.%s) which is not available", (*c)->module (), (*c)->name (), (*c)->declaration ()->module (), (*c)->declaration ()->name ()); + more_classes.push_back (*c); + continue; + } + 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 ()); diff --git a/src/pya/pya/pyaModule.cc b/src/pya/pya/pyaModule.cc index dd68e2e57..c89219c76 100644 --- a/src/pya/pya/pyaModule.cc +++ b/src/pya/pya/pyaModule.cc @@ -2377,8 +2377,18 @@ PythonModule::make_classes (const char *mod_name) continue; } - // there should be only main declarations since we merged - tl_assert ((*c)->declaration () == *c); + // we might encounter a child class which is a reference to a top-level class (e.g. + // duplication of enums into child classes). In this case we create a constant inside the + // target class. + if ((*c)->declaration () != *c) { + tl_assert ((*c)->parent () != 0); // top-level classes should be merged + PyTypeObject *parent_type = PythonClassClientData::py_type (*(*c)->parent ()->declaration ()); + PyTypeObject *type = PythonClassClientData::py_type (*(*c)->declaration ()); + tl_assert (type != 0); + PythonRef attr ((PyObject *) type, false /*borrowed*/); + set_type_attr (parent_type, (*c)->name ().c_str (), attr); + continue; + } // NOTE: we create the class as a heap object, since that way we can dynamically extend the objects @@ -2426,8 +2436,6 @@ PythonModule::make_classes (const char *mod_name) tl_assert (cls_for_type (type) == *c); - PyList_Append (all_list.get (), PythonRef (c2python ((*c)->name ())).get ()); - // Add to the parent class as child class or add to module if ((*c)->parent ()) { @@ -2436,6 +2444,7 @@ PythonModule::make_classes (const char *mod_name) PythonRef attr ((PyObject *) type); set_type_attr (parent_type, (*c)->name ().c_str (), attr); } else { + PyList_Append (all_list.get (), PythonRef (c2python ((*c)->name ())).get ()); PyModule_AddObject (module, (*c)->name ().c_str (), (PyObject *) type); } diff --git a/src/rba/rba/rba.cc b/src/rba/rba/rba.cc index 0cbf3faef..ad269b41b 100644 --- a/src/rba/rba/rba.cc +++ b/src/rba/rba/rba.cc @@ -1467,19 +1467,25 @@ rba_init (RubyInterpreterPrivateData *d) std::list sorted_classes = gsi::ClassBase::classes_in_definition_order (); for (std::list::const_iterator c = sorted_classes.begin (); c != sorted_classes.end (); ++c) { + // we might encounter a child class which is a reference to a top-level class (e.g. + // duplication of enums into child classes). In this case we create a constant inside the + // target class. + if ((*c)->declaration () != *c) { + tl_assert ((*c)->parent () != 0); // top-level classes should be merged + rb_define_const (ruby_cls ((*c)->parent ()->declaration ()), (*c)->name ().c_str (), ruby_cls ((*c)->declaration ())); + continue; + } + VALUE super = rb_cObject; if ((*c)->base () != 0) { tl_assert (is_registered ((*c)->base ())); super = ruby_cls ((*c)->base ()); } - // there should be only main declarations since we merged - tl_assert ((*c)->declaration () == *c); - VALUE klass; if ((*c)->parent ()) { - tl_assert (is_registered ((*c)->parent ())); - VALUE parent_class = ruby_cls ((*c)->parent ()); + tl_assert (is_registered ((*c)->parent ()->declaration ())); + VALUE parent_class = ruby_cls ((*c)->parent ()->declaration ()); klass = rb_define_class_under (parent_class, (*c)->name ().c_str (), super); } else { klass = rb_define_class_under (module, (*c)->name ().c_str (), super);