summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--offapi/UnoApi_offapi.mk1
-rw-r--r--offapi/org/libreoffice/embindtest/Template.idl21
-rw-r--r--offapi/org/libreoffice/embindtest/XTest.idl2
-rw-r--r--static/source/embindmaker/embindmaker.cxx171
-rw-r--r--unotest/source/embindtest/embindtest.cxx19
-rw-r--r--unotest/source/embindtest/embindtest.js10
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);