diff options
-rw-r--r-- | offapi/UnoApi_offapi.mk | 1 | ||||
-rw-r--r-- | offapi/org/libreoffice/embindtest/Template.idl | 21 | ||||
-rw-r--r-- | offapi/org/libreoffice/embindtest/XTest.idl | 2 | ||||
-rw-r--r-- | static/source/embindmaker/embindmaker.cxx | 171 | ||||
-rw-r--r-- | unotest/source/embindtest/embindtest.cxx | 19 | ||||
-rw-r--r-- | unotest/source/embindtest/embindtest.js | 10 |
6 files changed, 214 insertions, 10 deletions
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index b3c1c4e52ddf..9613a54eb27a 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -4448,6 +4448,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,org/libreoffice/embindtest, \ Struct \ StructLong \ StructString \ + Template \ XAttributes \ XTest \ )) diff --git a/offapi/org/libreoffice/embindtest/Template.idl b/offapi/org/libreoffice/embindtest/Template.idl new file mode 100644 index 000000000000..73e94a491307 --- /dev/null +++ b/offapi/org/libreoffice/embindtest/Template.idl @@ -0,0 +1,21 @@ +/* -*- 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 { + +struct Template<T1, T2> { + T2 m1; + long m2; + T1 m3; + T2 m4; +}; + +}; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/offapi/org/libreoffice/embindtest/XTest.idl b/offapi/org/libreoffice/embindtest/XTest.idl index 370363cf9a09..8d46c9e71d5a 100644 --- a/offapi/org/libreoffice/embindtest/XTest.idl +++ b/offapi/org/libreoffice/embindtest/XTest.idl @@ -44,6 +44,8 @@ interface XTest { boolean isStructLong([in] StructLong value); StructString getStructString(); boolean isStructString([in] StructString value); + Template<any, StructString> getTemplate(); + boolean isTemplate([in] Template<any, StructString> value); any getAnyVoid(); boolean isAnyVoid([in] any value); any getAnyBoolean(); diff --git a/static/source/embindmaker/embindmaker.cxx b/static/source/embindmaker/embindmaker.cxx index 9953512a8bf0..4956376bed16 100644 --- a/static/source/embindmaker/embindmaker.cxx +++ b/static/source/embindmaker/embindmaker.cxx @@ -262,7 +262,100 @@ void scan(rtl::Reference<unoidl::MapCursor> const& cursor, std::u16string_view p } } -OUString cppName(OUString const& name) { return "::" + name.replaceAll(u".", u"::"); } +OUString cppName(OUString const& name) +{ + sal_Int32 k; + std::vector<OString> args; + OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k, &args))); + OUStringBuffer buf; + for (sal_Int32 i = 0; i != k; ++i) + { + buf.append("::com::sun::star::uno::Sequence<"); + } + if (n == "boolean") + { + buf.append("::sal_Bool"); + } + else if (n == "byte") + { + buf.append("::sal_Int8"); + } + else if (n == "short") + { + buf.append("::sal_Int16"); + } + else if (n == "unsigned short") + { + buf.append("::sal_uInt16"); + } + else if (n == "long") + { + buf.append("::sal_Int32"); + } + else if (n == "unsigned long") + { + buf.append("::sal_uInt32"); + } + else if (n == "hyper") + { + buf.append("::sal_Int64"); + } + else if (n == "unsigned hyper") + { + buf.append("::sal_uInt64"); + } + else if (n == "float") + { + buf.append("float"); + } + else if (n == "double") + { + buf.append("double"); + } + else if (n == "char") + { + buf.append("::sal_Unicode"); + } + else if (n == "string") + { + buf.append("::rtl::OUString"); + } + else if (n == "type") + { + buf.append("::com::sun::star::uno::Type"); + } + else if (n == "any") + { + buf.append("::com::sun::star::uno::Any"); + } + else + { + buf.append("::" + n.replaceAll(u".", u"::")); + } + if (!args.empty()) + { + buf.append('<'); + bool first = true; + for (auto const& i : args) + { + if (first) + { + first = false; + } + else + { + buf.append(", "); + } + buf.append(cppName(b2u(i))); + } + buf.append('>'); + } + for (sal_Int32 i = 0; i != k; ++i) + { + buf.append('>'); + } + return buf.makeStringAndClear(); +} OUString resolveOuterTypedefs(rtl::Reference<TypeManager> const& manager, OUString const& name) { @@ -453,6 +546,16 @@ void dumpStructMembers(std::ostream& out, rtl::Reference<TypeManager> const& man } } +void dumpInstantiationMembers(std::ostream& out, OUString const& name, + rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity> poly) +{ + for (auto const& mem : poly->getMembers()) + { + out << "\n .field(\"" << mem.name << "\", &" << cppName(name) << "::" << mem.name + << ")"; + } +} + void dumpExceptionMembers(std::ostream& out, rtl::Reference<TypeManager> const& manager, OUString const& name, rtl::Reference<unoidl::ExceptionTypeEntity> exception) @@ -845,13 +948,32 @@ void dumpRegisterFunctionEpilog(std::ostream& out, unsigned long long& counter) } } -void recordSequenceTypes(rtl::Reference<TypeManager> const& manager, OUString const& type, - std::set<OUString>& sequences) +void recordGenericTypes(rtl::Reference<TypeManager> const& manager, OUString const& type, + std::set<OUString>& sequences, std::set<OUString>& instantiations) { auto const res = resolveAllTypedefs(manager, type); - if (manager->getSort(res) == codemaker::UnoType::Sort::Sequence) + switch (manager->getSort(res)) { - sequences.insert(res); + case codemaker::UnoType::Sort::Sequence: + if (sequences.insert(res).second) + { + assert(res.startsWith("[]")); + recordGenericTypes(manager, res.copy(2), sequences, instantiations); + } + break; + case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct: + if (instantiations.insert(res).second) + { + std::vector<OString> args; + codemaker::UnoType::decompose(u2b(res), nullptr, &args); + for (auto const& i : args) + { + recordGenericTypes(manager, b2u(i), sequences, instantiations); + } + } + break; + default: + break; } } @@ -995,6 +1117,7 @@ SAL_IMPLEMENT_MAIN() dumpRegisterFunctionEpilog(cppOut, n); } std::set<OUString> sequences; + std::set<OUString> instantiations; for (auto const& str : structs) { auto const ent = mgr->getManager()->findEntity(str); @@ -1010,7 +1133,7 @@ SAL_IMPLEMENT_MAIN() dumpRegisterFunctionEpilog(cppOut, n); for (auto const& mem : strEnt->getDirectMembers()) { - recordSequenceTypes(mgr, mem.type, sequences); + recordGenericTypes(mgr, mem.type, sequences, instantiations); } } for (auto const& exc : exceptions) @@ -1028,7 +1151,7 @@ SAL_IMPLEMENT_MAIN() dumpRegisterFunctionEpilog(cppOut, n); for (auto const& mem : excEnt->getDirectMembers()) { - recordSequenceTypes(mgr, mem.type, sequences); + recordGenericTypes(mgr, mem.type, sequences, instantiations); } } std::set<OUString> inOutParams; @@ -1097,20 +1220,48 @@ SAL_IMPLEMENT_MAIN() dumpRegisterFunctionEpilog(cppOut, n); for (auto const& attr : ifcEnt->getDirectAttributes()) { - recordSequenceTypes(mgr, attr.type, sequences); + recordGenericTypes(mgr, attr.type, sequences, instantiations); } for (auto const& meth : ifcEnt->getDirectMethods()) { for (auto const& param : meth.parameters) { - recordSequenceTypes(mgr, param.type, sequences); + recordGenericTypes(mgr, param.type, sequences, instantiations); if (param.direction != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN) { recordInOutParameterType(mgr, param.type, inOutParams); } } - recordSequenceTypes(mgr, meth.returnType, sequences); + recordGenericTypes(mgr, meth.returnType, sequences, instantiations); + } + } + for (auto const& ins : instantiations) + { + std::vector<OString> templArgs; + auto const templ = b2u(codemaker::UnoType::decompose(u2b(ins), nullptr, &templArgs)); + auto const ent = mgr->getManager()->findEntity(templ); + assert(ent.is()); + assert(ent->getSort() == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE); + rtl::Reference const polEnt( + static_cast<unoidl::PolymorphicStructTypeTemplateEntity*>(ent.get())); + dumpRegisterFunctionProlog(cppOut, n); + cppOut << " ::emscripten::value_object<" << cppName(ins) << ">(\"uno_Type_" + << jsName(ins) << "\")"; + dumpInstantiationMembers(cppOut, ins, polEnt); + cppOut << ";\n"; + cppOut << " ::unoembindhelpers::registerUnoType<" << cppName(ins) << ">();\n"; + dumpRegisterFunctionEpilog(cppOut, n); + for (auto const& arg : templArgs) + { + recordGenericTypes(mgr, b2u(arg), sequences, instantiations); + } + for (auto const& mem : polEnt->getMembers()) + { + if (!mem.parameterized) + { + recordGenericTypes(mgr, mem.type, sequences, instantiations); + } } } for (auto const& srv : services) diff --git a/unotest/source/embindtest/embindtest.cxx b/unotest/source/embindtest/embindtest.cxx index 166fa9650b8a..3883c031755c 100644 --- a/unotest/source/embindtest/embindtest.cxx +++ b/unotest/source/embindtest/embindtest.cxx @@ -30,6 +30,7 @@ #include <org/libreoffice/embindtest/Struct.hpp> #include <org/libreoffice/embindtest/StructLong.hpp> #include <org/libreoffice/embindtest/StructString.hpp> +#include <org/libreoffice/embindtest/Template.hpp> #include <org/libreoffice/embindtest/Test.hpp> #include <org/libreoffice/embindtest/XTest.hpp> #include <rtl/ustring.hxx> @@ -146,6 +147,24 @@ class Test : public cppu::WeakImplHelper<org::libreoffice::embindtest::XTest> return value.m == u"hä"; } + org::libreoffice::embindtest::Template<css::uno::Any, + org::libreoffice::embindtest::StructString> + SAL_CALL getTemplate() override + { + return { { u"foo"_ustr }, -123456, css::uno::Any(sal_Int32(-123456)), { u"barr"_ustr } }; + } + + sal_Bool SAL_CALL + isTemplate(org::libreoffice::embindtest::Template< + css::uno::Any, org::libreoffice::embindtest::StructString> const& value) override + { + return value + == org::libreoffice::embindtest::Template< + css::uno::Any, org::libreoffice::embindtest::StructString>{ + { u"foo"_ustr }, -123456, css::uno::Any(sal_Int32(-123456)), { u"barr"_ustr } + }; + } + css::uno::Any SAL_CALL getAnyVoid() override { return {}; } sal_Bool SAL_CALL isAnyVoid(css::uno::Any const& value) override diff --git a/unotest/source/embindtest/embindtest.js b/unotest/source/embindtest/embindtest.js index 42da2ee51b4e..57720b6baaa6 100644 --- a/unotest/source/embindtest/embindtest.js +++ b/unotest/source/embindtest/embindtest.js @@ -110,6 +110,16 @@ Module.uno_init.then(function() { v.m4.delete(); } { + let v = test.getTemplate(); + console.log(v); + console.assert(v.m1.m === 'foo'); + console.assert(v.m2 === -123456); + console.assert(v.m3.get() === -123456); + console.assert(v.m4.m === 'barr'); + console.assert(test.isTemplate(v)); + v.m3.delete(); + } + { let v = test.getAnyVoid(); console.log(v); console.assert(v.get() === undefined); |