static/source/embindmaker/embindmaker.cxx |  129 +++++++++++++++++++++++++++++-
 1 file changed, 125 insertions(+), 4 deletions(-)

New commits:
commit 5a521daa685dfe7922d057007530ed0711ba9e42
Author:     Stephan Bergmann <stephan.bergm...@allotropia.de>
AuthorDate: Wed Jan 31 13:28:22 2024 +0100
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Wed Jan 31 20:46:48 2024 +0100

    embindmaker: Handle (plain) structs
    
    Change-Id: I16ac3a6a2f42cf3054104a5ba90f4b75238e2ec4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162843
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de>

diff --git a/static/source/embindmaker/embindmaker.cxx 
b/static/source/embindmaker/embindmaker.cxx
index 178e9e41988a..d77973513bf4 100644
--- a/static/source/embindmaker/embindmaker.cxx
+++ b/static/source/embindmaker/embindmaker.cxx
@@ -139,8 +139,9 @@ jsServiceConstructor(OUString const& service,
 OUString jsSingleton(OUString const& singleton) { return "uno_Function_" + 
jsName(singleton); }
 
 void scan(rtl::Reference<unoidl::MapCursor> const& cursor, std::u16string_view 
prefix,
-          Module* module, std::vector<OUString>& enums, std::vector<OUString>& 
interfaces,
-          std::vector<OUString>& services, std::vector<OUString>& singletons)
+          Module* module, std::vector<OUString>& enums, std::vector<OUString>& 
structs,
+          std::vector<OUString>& interfaces, std::vector<OUString>& services,
+          std::vector<OUString>& singletons)
 {
     assert(cursor.is());
     assert(module != nullptr);
@@ -163,13 +164,18 @@ void scan(rtl::Reference<unoidl::MapCursor> const& 
cursor, std::u16string_view p
                     sub = std::make_shared<Module>();
                 }
                 
scan(static_cast<unoidl::ModuleEntity*>(ent.get())->createCursor(),
-                     Concat2View(name + "."), sub.get(), enums, interfaces, 
services, singletons);
+                     Concat2View(name + "."), sub.get(), enums, structs, 
interfaces, services,
+                     singletons);
                 break;
             }
             case unoidl::Entity::SORT_ENUM_TYPE:
                 module->mappings.emplace_back(id, "uno_Type_" + jsName(name));
                 enums.emplace_back(name);
                 break;
+            case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
+                module->mappings.emplace_back(id, "uno_Type_" + jsName(name));
+                structs.emplace_back(name);
+                break;
             case unoidl::Entity::SORT_INTERFACE_TYPE:
                 module->mappings.emplace_back(id, "uno_Type_" + jsName(name));
                 interfaces.emplace_back(name);
@@ -372,6 +378,89 @@ void dumpType(std::ostream& out, 
rtl::Reference<TypeManager> const& manager,
     }
 }
 
+bool hasStructMembers(rtl::Reference<TypeManager> const& manager,
+                      rtl::Reference<unoidl::PlainStructTypeEntity> struc)
+{
+    for (;;)
+    {
+        if (!struc->getDirectMembers().empty())
+        {
+            return true;
+        }
+        auto const& base = struc->getDirectBase();
+        if (base.isEmpty())
+        {
+            return false;
+        }
+        auto const ent = manager->getManager()->findEntity(base);
+        if (!ent.is() || ent->getSort() != 
unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
+        {
+            throw CannotDumpException("bad struct base \"" + base + "\"");
+        }
+        struc = static_cast<unoidl::PlainStructTypeEntity*>(ent.get());
+    }
+}
+
+void dumpStructMemberTypes(std::ostream& out, rtl::Reference<TypeManager> 
const& manager,
+                           rtl::Reference<unoidl::PlainStructTypeEntity> 
struc, bool& first)
+{
+    auto const& base = struc->getDirectBase();
+    if (!base.isEmpty())
+    {
+        auto const ent = manager->getManager()->findEntity(base);
+        if (!ent.is() || ent->getSort() != 
unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
+        {
+            throw CannotDumpException("bad struct base \"" + base + "\"");
+        }
+        dumpStructMemberTypes(out, manager, 
static_cast<unoidl::PlainStructTypeEntity*>(ent.get()),
+                              first);
+    }
+    for (auto const& mem : struc->getDirectMembers())
+    {
+        if (first)
+        {
+            first = false;
+        }
+        else
+        {
+            out << ", ";
+        }
+        dumpType(out, manager, mem.type);
+        if (passByReference(manager, mem.type))
+        {
+            out << " const &";
+        }
+    }
+}
+
+void dumpStructMembers(std::ostream& out, rtl::Reference<TypeManager> const& 
manager,
+                       OUString const& name, 
rtl::Reference<unoidl::PlainStructTypeEntity> struc)
+{
+    auto const& base = struc->getDirectBase();
+    if (!base.isEmpty())
+    {
+        auto const ent = manager->getManager()->findEntity(base);
+        if (!ent.is() || ent->getSort() != 
unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
+        {
+            throw CannotDumpException("bad struct base \"" + base + "\"");
+        }
+        dumpStructMembers(out, manager, name,
+                          
static_cast<unoidl::PlainStructTypeEntity*>(ent.get()));
+    }
+    for (auto const& mem : struc->getDirectMembers())
+    {
+        out << "
        .property(\"" << mem.name << "\", +[](" << cppName(name)
+            << " const & the_self) { return the_self." << mem.name << "; }, 
+[](" << cppName(name)
+            << " & the_self, ";
+        dumpType(out, manager, mem.type);
+        if (passByReference(manager, mem.type))
+        {
+            out << " const &";
+        }
+        out << " the_value) { the_self." << mem.name << " = the_value; })";
+    }
+}
+
 void dumpAttributes(std::ostream& out, rtl::Reference<TypeManager> const& 
manager,
                     OUString const& name, 
rtl::Reference<unoidl::InterfaceTypeEntity> const& entity,
                     std::list<OUString> const& baseTrail)
@@ -695,12 +784,13 @@ SAL_IMPLEMENT_MAIN()
         }
         auto const module = std::make_shared<Module>();
         std::vector<OUString> enums;
+        std::vector<OUString> structs;
         std::vector<OUString> interfaces;
         std::vector<OUString> services;
         std::vector<OUString> singletons;
         for (auto const& prov : mgr->getPrimaryProviders())
         {
-            scan(prov->createRootCursor(), u"", module.get(), enums, 
interfaces, services,
+            scan(prov->createRootCursor(), u"", module.get(), enums, structs, 
interfaces, services,
                  singletons);
         }
         std::ofstream cppOut(cppPathname, std::ios_base::out | 
std::ios_base::trunc);
@@ -717,6 +807,10 @@ SAL_IMPLEMENT_MAIN()
         {
             cppOut << "#include <" << enm.replace('.', '/') << ".hpp>
";
         }
+        for (auto const& str : structs)
+        {
+            cppOut << "#include <" << str.replace('.', '/') << ".hpp>
";
+        }
         for (auto const& ifc : interfaces)
         {
             cppOut << "#include <" << ifc.replace('.', '/') << ".hpp>
";
@@ -758,6 +852,33 @@ SAL_IMPLEMENT_MAIN()
             cppOut << ";
";
             dumpRegisterFunctionEpilog(cppOut, n);
         }
+        for (auto const& str : structs)
+        {
+            auto const ent = mgr->getManager()->findEntity(str);
+            assert(ent.is());
+            assert(ent->getSort() == unoidl::Entity::SORT_PLAIN_STRUCT_TYPE);
+            rtl::Reference const 
strEnt(static_cast<unoidl::PlainStructTypeEntity*>(ent.get()));
+            dumpRegisterFunctionProlog(cppOut, n);
+            cppOut << "    ::emscripten::class_<" << cppName(str);
+            auto const& base = strEnt->getDirectBase();
+            if (!base.isEmpty())
+            {
+                cppOut << ", ::emscripten::base<" << cppName(base) << ">";
+            }
+            cppOut << ">(\"uno_Type_" << jsName(str)
+                   << "\")
"
+                      "        .constructor()";
+            if (hasStructMembers(mgr, strEnt))
+            {
+                cppOut << "
        .constructor<";
+                auto first = true;
+                dumpStructMemberTypes(cppOut, mgr, strEnt, first);
+                cppOut << ">()";
+                dumpStructMembers(cppOut, mgr, str, strEnt);
+            }
+            cppOut << ";
";
+            dumpRegisterFunctionEpilog(cppOut, n);
+        }
         for (auto const& ifc : interfaces)
         {
             auto const ent = mgr->getManager()->findEntity(ifc);

Reply via email to