Embind: Consistently represent empty interface references as JS null

The existing code had two issues:  For one, e.g. calling a function that
returned a null interface reference mapped that to JS null, while querying an
object for a non-supported interface via `new css.uno.X...(y)` mapped that to
an "empty" JS object instead.  (So checking for a non-null reference needed to
be done as either `x !=== null` or as `x.is()`, depending on context.)  And for
another, while calling $is() on a non-"empty" object worked fine, it failed on
such an "empty" object (as the Embind internals of that object lacked the $$
property).

So change the querying mechanism from the `new css.uno.X...(y)` constructor to a
`css.uno.X....query(y)` function call syntax, which now returns JS null when
querying for a non-supported interface.  (And drop the broken $is method.)

Change-Id: I8fa488ab2892423f2a461d9b72db47e1d4df3b8d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166255
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
This commit is contained in:
Stephan Bergmann
2024-04-19 21:20:59 +02:00
parent 41706fcd96
commit 1c81f63e91
5 changed files with 36 additions and 15 deletions
@@ -112,6 +112,8 @@ interface XTest {
boolean isSequenceEnum([in] sequence<Enum> value);
sequence<Struct> getSequenceStruct();
boolean isSequenceStruct([in] sequence<Struct> value);
XTest getNull();
boolean isNull([in] XTest value);
void throwRuntimeException();
void passJob([in] com::sun::star::task::XJob object);
void passJobExecutor([in] com::sun::star::task::XJobExecutor object);
+7 -7
View File
@@ -228,11 +228,11 @@ Some usage examples through javascript of the current implementation:
let uno = init_unoembind_uno(Module);
let css = uno.com.sun.star;
xModel = Module.getCurrentModelFromViewSh();
xTextDocument = new css.text.XTextDocument(xModel);
xTextDocument = css.text.XTextDocument.query(xModel);
xText = xTextDocument.getText();
xSimpleText = new css.text.XSimpleText(xText);
xSimpleText = css.text.XSimpleText.query(xText);
xTextCursor = xSimpleText.createTextCursor();
xTextRange = new css.text.XTextRange(xTextCursor);
xTextRange = css.text.XTextRange.query(xTextCursor);
xTextRange.setString("string here!");
xModel.delete(); xTextDocument.delete(); xText.delete(); xSimpleText.delete(); xTextCursor.delete(); xTextRange.delete();
```
@@ -242,13 +242,13 @@ xModel.delete(); xTextDocument.delete(); xText.delete(); xSimpleText.delete(); x
let uno = init_unoembind_uno(Module);
let css = uno.com.sun.star;
xModel = Module.getCurrentModelFromViewSh();
xEnumAccess = new css.container.XEnumerationAccess(xText);
xEnumAccess = css.container.XEnumerationAccess.query(xText);
xParaEnumeration = xEnumAccess.createEnumeration();
while (xParaEnumeration.hasMoreElements()) {
xParagraph = new css.text.XTextRange(xParaEnumeration.nextElement().get());
if (xParagraph.$is()) {
xParaProps = new css.beans.XPropertySet(xParagraph);
xParagraph = css.text.XTextRange.query(xParaEnumeration.nextElement().get());
if (xParagraph !== null) {
xParaProps = css.beans.XPropertySet.query(xParagraph);
let color = new Module.uno_Any(
Module.uno_Type.Long(), Math.floor(Math.random() * 0xFFFFFF));
xParaProps.setPropertyValue("CharColor", color);
+5 -8
View File
@@ -1082,18 +1082,15 @@ SAL_IMPLEMENT_MAIN()
" .smart_ptr<::com::sun::star::uno::Reference<"
<< cppName(ifc) << ">>(\"uno_Reference_" << jsName(ifc)
<< "\")\n"
" .class_function(\"query\", "
"+[](::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> "
"const & the_object) { return ::com::sun::star::uno::Reference<"
<< cppName(ifc)
<< ">(the_object, ::com::sun::star::uno::UNO_QUERY); })\n"
" .class_function(\"reference\", +[]("
<< cppName(ifc)
<< " * the_interface) { return ::com::sun::star::uno::Reference(the_interface); "
"}, ::emscripten::allow_raw_pointers())\n"
" "
".constructor(+[](::com::sun::star::uno::Reference<::com::sun::star::uno::"
"XInterface> const & the_object) { return ::com::sun::star::uno::Reference<"
<< cppName(ifc)
<< ">(the_object, ::com::sun::star::uno::UNO_QUERY); })\n"
" .function(\"$is\", +[](::com::sun::star::uno::Reference<"
<< cppName(ifc)
<< "> const & the_self) { return the_self.is(); })\n"
" .function(\"$equals\", +[](::com::sun::star::uno::Reference<"
<< cppName(ifc)
<< "> const & the_self, "
+11
View File
@@ -501,6 +501,17 @@ class Test : public cppu::WeakImplHelper<org::libreoffice::embindtest::XTest>
};
}
css::uno::Reference<org::libreoffice::embindtest::XTest> SAL_CALL getNull() override
{
return {};
}
sal_Bool SAL_CALL
isNull(css::uno::Reference<org::libreoffice::embindtest::XTest> const& value) override
{
return !value;
}
void SAL_CALL throwRuntimeException() override
{
throw css::uno::RuntimeException(u"test"_ustr);
+11
View File
@@ -517,6 +517,17 @@ Module.addOnPostRun(function() {
console.assert(test.isSequenceStruct(v));
v.delete();
}
{
let v = test.getNull();
console.log(v);
console.assert(v === null);
console.assert(test.isNull(v));
}
{
let v = css.task.XJob.query(test);
console.log(v);
console.assert(v === null);
}
console.assert(uno.org.libreoffice.embindtest.Constants.Boolean === true);
console.assert(test.isBoolean(uno.org.libreoffice.embindtest.Constants.Boolean));
console.assert(uno.org.libreoffice.embindtest.Constants.Byte === -12);