summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorStephan Bergmann <stephan.bergmann@allotropia.de>2024-01-31 13:28:22 +0100
committerStephan Bergmann <stephan.bergmann@allotropia.de>2024-01-31 20:46:48 +0100
commit5a521daa685dfe7922d057007530ed0711ba9e42 (patch)
treeddca7fea4b4de2ccdfc9ef3e5f23ae680307f1c4 /static
parentda733de7e2721c6e5982a90953f09a2769af0a30 (diff)
embindmaker: Handle (plain) structs
Change-Id: I16ac3a6a2f42cf3054104a5ba90f4b75238e2ec4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162843 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Diffstat (limited to 'static')
-rw-r--r--static/source/embindmaker/embindmaker.cxx129
1 files changed, 125 insertions, 4 deletions
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 << "\n .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>\n";
}
+ for (auto const& str : structs)
+ {
+ cppOut << "#include <" << str.replace('.', '/') << ".hpp>\n";
+ }
for (auto const& ifc : interfaces)
{
cppOut << "#include <" << ifc.replace('.', '/') << ".hpp>\n";
@@ -758,6 +852,33 @@ SAL_IMPLEMENT_MAIN()
cppOut << ";\n";
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)
+ << "\")\n"
+ " .constructor()";
+ if (hasStructMembers(mgr, strEnt))
+ {
+ cppOut << "\n .constructor<";
+ auto first = true;
+ dumpStructMemberTypes(cppOut, mgr, strEnt, first);
+ cppOut << ">()";
+ dumpStructMembers(cppOut, mgr, str, strEnt);
+ }
+ cppOut << ";\n";
+ dumpRegisterFunctionEpilog(cppOut, n);
+ }
for (auto const& ifc : interfaces)
{
auto const ent = mgr->getManager()->findEntity(ifc);