Add JS generator support for css.container.XEnumerationAccess
...similar to <https://github.com/allotropia/zetajs/commit/ea7bfb5ac1ede0aa3ed92bb14e55ddaadcd23d22> "Add JS generator support for css.container.XEnumerationAccess" Signed-off-by: Stephan Bergmann <stephan.bergmann@collabora.com> Change-Id: I793045d534e3b2a62de24c44689797ec24d3d555 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1612 Reviewed-by: Michael Stahl <michael.stahl@collabora.com> Tested-by: Jenkins CPCI <releng@collaboraoffice.com> (cherry picked from commit ef35e615ea97b0cd6526b0935a7da5d57cd3a535) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205116 Reviewed-by: Neil Roberts <nroberts@libreoffice.org> Tested-by: Jenkins
This commit is contained in:
committed by
Neil Roberts
parent
f79a4848f9
commit
faeda637f6
+80
-4
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <quickjs.h>
|
||||
|
||||
#include <com/sun/star/container/XEnumeration.hpp>
|
||||
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
|
||||
#include <com/sun/star/reflection/InvocationTargetException.hpp>
|
||||
#include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
|
||||
@@ -68,13 +69,26 @@ struct JsException
|
||||
class AtomRef
|
||||
{
|
||||
public:
|
||||
AtomRef(JSRuntime* rt)
|
||||
: rt_(rt)
|
||||
, atom_(JS_ATOM_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AtomRef(JSContext* ctx, JSAtom atom)
|
||||
: ctx_(ctx)
|
||||
: rt_(JS_GetRuntime(ctx))
|
||||
, atom_(atom)
|
||||
{
|
||||
}
|
||||
|
||||
~AtomRef() { JS_FreeAtom(ctx_, atom_); }
|
||||
~AtomRef() { JS_FreeAtomRT(rt_, atom_); }
|
||||
|
||||
AtomRef& operator=(JSAtom atom)
|
||||
{
|
||||
std::swap(atom_, atom);
|
||||
JS_FreeAtomRT(rt_, atom);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator JSAtom() const { return atom_; }
|
||||
|
||||
@@ -84,7 +98,7 @@ private:
|
||||
void operator=(AtomRef const&) = delete;
|
||||
void operator=(AtomRef&&) = delete;
|
||||
|
||||
JSContext* ctx_;
|
||||
JSRuntime* rt_;
|
||||
JSAtom atom_;
|
||||
};
|
||||
|
||||
@@ -221,6 +235,13 @@ private:
|
||||
|
||||
struct RuntimeData
|
||||
{
|
||||
RuntimeData(JSRuntime* rt)
|
||||
: symbolIteratorAtom(rt)
|
||||
{
|
||||
}
|
||||
|
||||
void clear() { symbolIteratorAtom = JS_ATOM_NULL; }
|
||||
|
||||
JSClassID pointerClassId = 0;
|
||||
JSClassID wrapperClassId = 0;
|
||||
JSClassID enumeratorClassId = 0;
|
||||
@@ -234,6 +255,8 @@ struct RuntimeData
|
||||
JSClassID singletonClassId = 0;
|
||||
JSClassID moduleClassId = 0;
|
||||
|
||||
AtomRef symbolIteratorAtom;
|
||||
|
||||
#if defined DBG_UTIL
|
||||
Counter toFinalize;
|
||||
#endif
|
||||
@@ -335,9 +358,57 @@ void pointerFinalizer(JSRuntime* rt, JSValueConst val)
|
||||
JS_GetOpaque(val, getRuntimeData(rt)->pointerClassId));
|
||||
}
|
||||
|
||||
JSValue enumerationIteratorNext(JSContext* ctx, JSValueConst, int, JSValueConst*, int,
|
||||
JSValueConst* func_data)
|
||||
{
|
||||
return callFromJs(ctx, [ctx, func_data] {
|
||||
css::uno::Reference<css::container::XEnumeration> en(
|
||||
static_cast<css::uno::XInterface*>(
|
||||
JS_GetOpaque(func_data[0], getRuntimeData(ctx)->wrapperClassId)),
|
||||
css::uno::UNO_QUERY_THROW);
|
||||
ValueRef val(ctx, JS_NewObject(ctx));
|
||||
if (en->hasMoreElements())
|
||||
{
|
||||
JS_SetPropertyStr(ctx, val, "value", toJs(ctx, en->nextElement()).release());
|
||||
JS_SetPropertyStr(ctx, val, "done", JS_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
JS_SetPropertyStr(ctx, val, "value", JS_UNDEFINED);
|
||||
JS_SetPropertyStr(ctx, val, "done", JS_TRUE);
|
||||
}
|
||||
return val.release();
|
||||
});
|
||||
}
|
||||
|
||||
JSValue enumerationIterator(JSContext* ctx, JSValueConst this_val, int, JSValueConst*)
|
||||
{
|
||||
return callFromJs(ctx, [ctx, this_val] {
|
||||
ValueRef iter(ctx, JS_NewObject(ctx));
|
||||
JS_SetPropertyStr(ctx, iter, "next",
|
||||
JS_NewCFunctionData(ctx, enumerationIteratorNext, 0, 0, 1,
|
||||
const_cast<JSValueConst*>(&this_val)));
|
||||
return iter.release();
|
||||
});
|
||||
}
|
||||
|
||||
JSValue wrapperGetProperty(JSContext* ctx, JSValueConst obj, JSAtom atom, JSValueConst receiver)
|
||||
{
|
||||
return callFromJs(ctx, [ctx, obj, atom, receiver] {
|
||||
if (atom == getRuntimeData(ctx)->symbolIteratorAtom)
|
||||
{
|
||||
css::uno::Reference<css::container::XEnumeration> en(
|
||||
static_cast<css::uno::XInterface*>(
|
||||
JS_GetOpaque(obj, getRuntimeData(ctx)->wrapperClassId)),
|
||||
css::uno::UNO_QUERY);
|
||||
if (!en.is())
|
||||
{
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
ValueRef val(ctx, JS_NewCFunction(ctx, enumerationIterator, "[Symbol.iterator]", 0));
|
||||
JS_SetProperty(ctx, receiver, atom, val.dup());
|
||||
return val.release();
|
||||
}
|
||||
ValueRef const v(ctx, JS_AtomToString(ctx, atom));
|
||||
if (!JS_IsString(v))
|
||||
{
|
||||
@@ -2369,7 +2440,7 @@ JSValue invokeUno(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst*
|
||||
void jsuno::execute(OUString const& script)
|
||||
{
|
||||
auto const rt = JS_NewRuntime();
|
||||
JS_SetRuntimeOpaque(rt, new RuntimeData);
|
||||
JS_SetRuntimeOpaque(rt, new RuntimeData(rt));
|
||||
JS_NewClassID(rt, &getRuntimeData(rt)->pointerClassId);
|
||||
JSClassDef pointerClass{ "InternalPointer", pointerFinalizer, nullptr, nullptr, nullptr };
|
||||
[[maybe_unused]] auto e = JS_NewClass(rt, getRuntimeData(rt)->pointerClassId, &pointerClass);
|
||||
@@ -2429,6 +2500,10 @@ void jsuno::execute(OUString const& script)
|
||||
std::optional<OUString> exc;
|
||||
{
|
||||
ValueRef const global(ctx, JS_GetGlobalObject(ctx));
|
||||
getRuntimeData(ctx)->symbolIteratorAtom = JS_ValueToAtom(
|
||||
ctx, ValueRef(ctx, JS_GetPropertyStr(
|
||||
ctx, ValueRef(ctx, JS_GetPropertyStr(ctx, global, "Symbol")),
|
||||
"iterator")));
|
||||
ValueRef console(ctx, JS_NewObject(ctx));
|
||||
JS_SetPropertyStr(ctx, console, "assert", JS_NewCFunction(ctx, consoleAssert, "assert", 1));
|
||||
JS_SetPropertyStr(ctx, console, "log", JS_NewCFunction(ctx, consoleLog, "log", 0));
|
||||
@@ -2501,6 +2576,7 @@ void jsuno::execute(OUString const& script)
|
||||
}
|
||||
JS_FreeContext(ctx);
|
||||
std::unique_ptr<RuntimeData> data(getRuntimeData(rt));
|
||||
data->clear();
|
||||
JS_FreeRuntime(rt);
|
||||
if (exc)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user