static/source/embindmaker/embindmaker.cxx | 61 ++++++++++++++++++--- static/source/unoembindhelpers/PrimaryBindings.cxx | 9 +-- udkapi/UnoApi_udkapi.mk | 1 udkapi/org/libreoffice/embindtest/Exception.idl | 20 ++++++ udkapi/org/libreoffice/embindtest/XTest.idl | 2 unotest/source/embindtest/embindtest.cxx | 18 ++++++ unotest/source/embindtest/embindtest.js | 16 +++++ 7 files changed, 116 insertions(+), 11 deletions(-)
New commits: commit 567a10caef0f2ebc9390babda545b410b5aa36c6 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Tue Mar 5 16:37:01 2024 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Wed Mar 6 00:02:36 2024 +0100 Add Embind'ing of UNO Any getter for exceptions Change-Id: Ief3cdebc1ee7c7b9f012741c9db8637dba9bbd07 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164433 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 a0ea41eddf97..a3558e5b4e04 100644 --- a/static/source/embindmaker/embindmaker.cxx +++ b/static/source/embindmaker/embindmaker.cxx @@ -141,8 +141,8 @@ OUString jsSingleton(OUString const& singleton) { return "uno_Function_" + jsNam void scan(rtl::Reference<unoidl::MapCursor> const& cursor, std::u16string_view prefix, Module* module, std::vector<OUString>& enums, std::vector<OUString>& structs, - std::vector<OUString>& interfaces, std::vector<OUString>& services, - std::vector<OUString>& singletons) + std::vector<OUString>& exceptions, std::vector<OUString>& interfaces, + std::vector<OUString>& services, std::vector<OUString>& singletons) { assert(cursor.is()); assert(module != nullptr); @@ -165,8 +165,8 @@ 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, structs, interfaces, services, - singletons); + Concat2View(name + "."), sub.get(), enums, structs, exceptions, interfaces, + services, singletons); break; } case unoidl::Entity::SORT_ENUM_TYPE: @@ -177,6 +177,10 @@ void scan(rtl::Reference<unoidl::MapCursor> const& cursor, std::u16string_view p module->mappings.emplace_back(id, "instance.uno_Type_" + jsName(name)); structs.emplace_back(name); break; + case unoidl::Entity::SORT_EXCEPTION_TYPE: + module->mappings.emplace_back(id, "instance.uno_Type_" + jsName(name)); + exceptions.emplace_back(name); + break; case unoidl::Entity::SORT_INTERFACE_TYPE: module->mappings.emplace_back(id, "instance.uno_Type_" + jsName(name)); interfaces.emplace_back(name); @@ -449,6 +453,28 @@ void dumpStructMembers(std::ostream& out, rtl::Reference<TypeManager> const& man } } +void dumpExceptionMembers(std::ostream& out, rtl::Reference<TypeManager> const& manager, + OUString const& name, + rtl::Reference<unoidl::ExceptionTypeEntity> exception) +{ + auto const& base = exception->getDirectBase(); + if (!base.isEmpty()) + { + auto const ent = manager->getManager()->findEntity(base); + if (!ent.is() || ent->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE) + { + throw CannotDumpException("bad exception base \"" + base + "\""); + } + dumpExceptionMembers(out, manager, name, + static_cast<unoidl::ExceptionTypeEntity*>(ent.get())); + } + for (auto const& mem : exception->getDirectMembers()) + { + out << " .field(\"" << mem.name << "\", &" << cppName(name) << "::" << mem.name + << ")"; + } +} + void dumpAttributes(std::ostream& out, rtl::Reference<TypeManager> const& manager, OUString const& name, rtl::Reference<unoidl::InterfaceTypeEntity> const& entity, std::list<OUString> const& baseTrail) @@ -784,13 +810,14 @@ SAL_IMPLEMENT_MAIN() auto const module = std::make_shared<Module>(); std::vector<OUString> enums; std::vector<OUString> structs; + std::vector<OUString> exceptions; 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, structs, interfaces, services, - singletons); + scan(prov->createRootCursor(), u"", module.get(), enums, structs, exceptions, + interfaces, services, singletons); } std::ofstream cppOut(cppPathname, std::ios_base::out | std::ios_base::trunc); if (!cppOut) @@ -810,6 +837,10 @@ SAL_IMPLEMENT_MAIN() { cppOut << "#include <" << str.replace('.', '/') << ".hpp> "; } + for (auto const& exc : exceptions) + { + cppOut << "#include <" << exc.replace('.', '/') << ".hpp> "; + } for (auto const& ifc : interfaces) { cppOut << "#include <" << ifc.replace('.', '/') << ".hpp> "; @@ -871,6 +902,24 @@ SAL_IMPLEMENT_MAIN() recordSequenceTypes(mgr, mem.type, sequences); } } + for (auto const& exc : exceptions) + { + auto const ent = mgr->getManager()->findEntity(exc); + assert(ent.is()); + assert(ent->getSort() == unoidl::Entity::SORT_EXCEPTION_TYPE); + rtl::Reference const excEnt(static_cast<unoidl::ExceptionTypeEntity*>(ent.get())); + dumpRegisterFunctionProlog(cppOut, n); + cppOut << " ::emscripten::value_object<" << cppName(exc) << ">(\"uno_Type_" + << jsName(exc) << "\")"; + dumpExceptionMembers(cppOut, mgr, exc, excEnt); + cppOut << "; "; + cppOut << " ::unoembindhelpers::registerUnoType<" << cppName(exc) << ">(); "; + dumpRegisterFunctionEpilog(cppOut, n); + for (auto const& mem : excEnt->getDirectMembers()) + { + recordSequenceTypes(mgr, mem.type, sequences); + } + } for (auto const& ifc : interfaces) { auto const ent = mgr->getManager()->findEntity(ifc); diff --git a/static/source/unoembindhelpers/PrimaryBindings.cxx b/static/source/unoembindhelpers/PrimaryBindings.cxx index 21fe4c1cd66f..93ae89531a00 100644 --- a/static/source/unoembindhelpers/PrimaryBindings.cxx +++ b/static/source/unoembindhelpers/PrimaryBindings.cxx @@ -318,18 +318,17 @@ EMSCRIPTEN_BINDINGS(PrimaryBindings) _emval_take_value(getTypeId(self.getValueType()), argv)); } case css::uno::TypeClass_STRUCT: + case css::uno::TypeClass_EXCEPTION: { css::uno::TypeDescription desc(self.getValueType().getTypeLibType()); assert(desc.is()); - auto const td = reinterpret_cast<typelib_StructTypeDescription*>(desc.get()); - auto const copy = std::malloc(td->aBase.aBase.nSize); - copyStruct(&td->aBase, self.getValue(), copy); + auto const td = reinterpret_cast<typelib_CompoundTypeDescription*>(desc.get()); + auto const copy = std::malloc(td->aBase.nSize); + copyStruct(td, self.getValue(), copy); emscripten::internal::WireTypePack argv(std::move(copy)); return emscripten::val::take_ownership( _emval_take_value(getTypeId(self.getValueType()), argv)); } - case css::uno::TypeClass_EXCEPTION: - return emscripten::val::undefined(); //TODO case css::uno::TypeClass_INTERFACE: return emscripten::val::undefined(); //TODO default: diff --git a/udkapi/UnoApi_udkapi.mk b/udkapi/UnoApi_udkapi.mk index 34117950d64e..1e338c807e07 100644 --- a/udkapi/UnoApi_udkapi.mk +++ b/udkapi/UnoApi_udkapi.mk @@ -524,6 +524,7 @@ ifeq ($(OS)-$(ENABLE_DBGUTIL),EMSCRIPTEN-TRUE) $(eval $(call gb_UnoApi_add_idlfiles,udkapi,org/libreoffice/embindtest, \ Constants \ Enum \ + Exception \ Struct \ XTest \ )) diff --git a/udkapi/org/libreoffice/embindtest/Exception.idl b/udkapi/org/libreoffice/embindtest/Exception.idl new file mode 100644 index 000000000000..cc6e89d35df9 --- /dev/null +++ b/udkapi/org/libreoffice/embindtest/Exception.idl @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +module org { module libreoffice { module embindtest { + +exception Exception: com::sun::star::uno::Exception { + long m1; + double m2; + string m3; +}; + +}; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/udkapi/org/libreoffice/embindtest/XTest.idl b/udkapi/org/libreoffice/embindtest/XTest.idl index 3338cf130f98..e5b5a4535982 100644 --- a/udkapi/org/libreoffice/embindtest/XTest.idl +++ b/udkapi/org/libreoffice/embindtest/XTest.idl @@ -74,6 +74,8 @@ interface XTest { boolean isAnyEnum([in] any value); any getAnyStruct(); boolean isAnyStruct([in] any value); + any getAnyException(); + boolean isAnyException([in] any value); sequence<boolean> getSequenceBoolean(); boolean isSequenceBoolean([in] sequence<boolean> value); sequence<byte> getSequenceByte(); diff --git a/unotest/source/embindtest/embindtest.cxx b/unotest/source/embindtest/embindtest.cxx index 4570eb4822f8..260c9883eb19 100644 --- a/unotest/source/embindtest/embindtest.cxx +++ b/unotest/source/embindtest/embindtest.cxx @@ -17,6 +17,7 @@ #include <cppuhelper/weak.hxx> #include <o3tl/any.hxx> #include <org/libreoffice/embindtest/Enum.hpp> +#include <org/libreoffice/embindtest/Exception.hpp> #include <org/libreoffice/embindtest/Struct.hpp> #include <org/libreoffice/embindtest/XTest.hpp> #include <rtl/ustring.hxx> @@ -265,6 +266,23 @@ class Test : public cppu::WeakImplHelper<org::libreoffice::embindtest::XTest> == org::libreoffice::embindtest::Struct{ -123456, 100.5, u"hä"_ustr }; } + css::uno::Any SAL_CALL getAnyException() override + { + return css::uno::Any(org::libreoffice::embindtest::Exception{ + u"error"_ustr, {}, -123456, 100.5, u"hä"_ustr }); + } + + sal_Bool SAL_CALL isAnyException(css::uno::Any const& value) override + { + if (value.getValueType() != cppu::UnoType<org::libreoffice::embindtest::Exception>::get()) + { + return false; + } + auto const& e = *o3tl::forceAccess<org::libreoffice::embindtest::Exception>(value); + return e.Message == "error" && !e.Context.is() && e.m1 == -123456 && e.m2 == 100.5 + && e.m3 == u"hä"; + } + css::uno::Sequence<sal_Bool> SAL_CALL getSequenceBoolean() override { return { true, true, false }; diff --git a/unotest/source/embindtest/embindtest.js b/unotest/source/embindtest/embindtest.js index b10e98b9efa4..9b9911826219 100644 --- a/unotest/source/embindtest/embindtest.js +++ b/unotest/source/embindtest/embindtest.js @@ -286,6 +286,22 @@ Module.addOnPostRun(function() { //TODO: console.assert(test.isAnyStruct(a)); //TODO: a.delete(); } + { + let v = test.getAnyException(); + console.log(v); + console.assert(v.get().Message === 'error'); + console.assert(v.get().Context === null); + console.assert(v.get().m1 === -123456); + console.assert(v.get().m2 === 100.5); + console.assert(v.get().m3 === 'hä'); + console.assert(test.isAnyException(v)); + v.delete(); + //TODO: let a = new Module.Any( + //TODO: {Message: 'error', Context: null, m1: -123456, m2: 100.5, m3: 'hä'}, + //TODO: css.uno.TypeClass.EXCEPTION); + //TODO: console.assert(test.isAnyException(a)); + //TODO: a.delete(); + } { let v = test.getSequenceBoolean(); console.log(v);