[gjs/march-maintenance: 7/11] wrapperutils: Move is_custom_js_class()
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/march-maintenance: 7/11] wrapperutils: Move is_custom_js_class()
- Date: Tue, 31 Mar 2020 04:47:45 +0000 (UTC)
commit 81b81abdf992637e11d41db8bf4ecace5a9e7ff4
Author: Philip Chimento <philip chimento gmail com>
Date: Wed Mar 11 22:32:22 2020 -0700
wrapperutils: Move is_custom_js_class()
This name of GIWrapperBase::is_custom_js_class() is misleading. If there
is no GI introspection info, then the class may be a custom JS class,
but it could also be an internal class not exposed through
introspection, like GLocalFile.
In most cases is_custom_js_class() can just be replaced with !info().
In one case of existing usage of is_custom_js_class(), we really do mean
it, in add_property_impl(). For this we check the custom_type_quark() on
the GType. For better readability, this adds an is_custom_js_class()
method to ObjectBase which actually does what it says.
See also #299 and commit 74171bf3ae91ff64337b6261fe024e34e073f86f.
gi/interface.cpp | 2 +-
gi/object.cpp | 33 ++++++++++++++++++---------------
gi/object.h | 1 +
gi/wrapperutils.h | 31 +++++++++++++++----------------
4 files changed, 35 insertions(+), 32 deletions(-)
---
diff --git a/gi/interface.cpp b/gi/interface.cpp
index 7ad150ec..3dc0a362 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -56,7 +56,7 @@ bool InterfacePrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
/* If we have no GIRepository information then this interface was defined
* from within GJS. In that case, it has no properties that need to be
* resolved from within C code, as interfaces cannot inherit. */
- if (is_custom_js_class()) {
+ if (!info()) {
*resolved = false;
return true;
}
diff --git a/gi/object.cpp b/gi/object.cpp
index 7bc942b9..96e2062a 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -107,6 +107,10 @@ gjs_object_priv_quark (void)
return val;
}
+bool ObjectBase::is_custom_js_class() {
+ return !!g_type_get_qdata(gtype(), ObjectBase::custom_type_quark());
+}
+
// Plain g_type_query fails and leaves @query uninitialized for dynamic types.
// See https://gitlab.gnome.org/GNOME/glib/issues/623
void ObjectBase::type_query_dynamic_safe(GTypeQuery* query) {
@@ -673,8 +677,7 @@ bool ObjectPrototype::resolve_no_info(JSContext* cx, JS::HandleObject obj,
/* Fallback to GType system for non custom GObjects with no GI information
*/
- if (canonical_name && G_TYPE_IS_CLASSED(m_gtype) &&
- !g_type_get_qdata(m_gtype, ObjectInstance::custom_type_quark())) {
+ if (canonical_name && G_TYPE_IS_CLASSED(m_gtype) && !is_custom_js_class()) {
GjsAutoTypeClass<GObjectClass> oclass(m_gtype);
if (g_object_class_find_property(oclass, canonical_name))
@@ -786,10 +789,11 @@ bool ObjectPrototype::resolve_impl(JSContext* context, JS::HandleObject obj,
bool ObjectPrototype::uncached_resolve(JSContext* context, JS::HandleObject obj,
JS::HandleId id, const char* name,
bool* resolved) {
- /* If we have no GIRepository information (we're a JS GObject subclass),
- * we need to look at exposing interfaces. Look up our interfaces through
- * GType data, and then hope that *those* are introspectable. */
- if (is_custom_js_class())
+ // If we have no GIRepository information (we're a JS GObject subclass or an
+ // internal non-introspected class such as GLocalFile), we need to look at
+ // exposing interfaces. Look up our interfaces through GType data, and then
+ // hope that *those* are introspectable.
+ if (!info())
return resolve_no_info(context, obj, id, resolved, name,
ConsiderMethodsAndProperties);
@@ -962,7 +966,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
g_free(interfaces);
- if (!is_custom_js_class()) {
+ if (info()) {
// Methods
int n_methods = g_object_info_get_n_methods(info());
for (int i = 0; i < n_methods; i++) {
@@ -1517,11 +1521,9 @@ ObjectInstance::init_impl(JSContext *context,
return false;
}
- /* Mark this object in the construction stack, it
- will be popped in gjs_object_custom_init() later
- down.
- */
- if (g_type_get_qdata(gtype(), ObjectInstance::custom_type_quark())) {
+ // Mark this object in the construction stack, it will be popped in
+ // gjs_object_custom_init() in gi/gobject.cpp.
+ if (is_custom_js_class()) {
GjsContextPrivate* gjs = GjsContextPrivate::from_cx(context);
if (!gjs->object_init_list().append(object)) {
JS_ReportOutOfMemory(context);
@@ -1763,9 +1765,10 @@ gjs_lookup_object_prototype(JSContext *context,
// The caller does not own the return value, and it can never be null.
GIFieldInfo* ObjectPrototype::lookup_cached_field_info(JSContext* cx,
JS::HandleString key) {
- if (is_custom_js_class()) {
- // Custom JS classes can't have fields. We must be looking up a field on
- // a GObject-introspected parent.
+ if (!info()) {
+ // Custom JS classes can't have fields, and fields on internal classes
+ // are not available. We must be looking up a field on a
+ // GObject-introspected parent.
GType parent_gtype = g_type_parent(m_gtype);
g_assert(parent_gtype != G_TYPE_INVALID &&
"Custom JS class must have parent");
diff --git a/gi/object.h b/gi/object.h
index 583ba1d4..b6f11e5c 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -137,6 +137,7 @@ class ObjectBase
}
bool id_is_never_lazy(jsid name, const GjsAtoms& atoms);
+ GJS_USE bool is_custom_js_class();
public:
void type_query_dynamic_safe(GTypeQuery* query);
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index bcb3203a..e8f1f430 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -287,18 +287,16 @@ class GIWrapperBase {
GJS_USE GIBaseInfo* info(void) const { return get_prototype()->info(); }
GJS_USE GType gtype(void) const { return get_prototype()->gtype(); }
- // The next four methods are operations derived from the GIFooInfo.
+ // The next three methods are operations derived from the GIFooInfo.
- GJS_USE bool is_custom_js_class(void) const { return !info(); }
GJS_USE const char* type_name(void) const { return g_type_name(gtype()); }
GJS_USE
const char* ns(void) const {
- return is_custom_js_class() ? "" : g_base_info_get_namespace(info());
+ return info() ? g_base_info_get_namespace(info()) : "";
}
GJS_USE
const char* name(void) const {
- return is_custom_js_class() ? type_name()
- : g_base_info_get_name(info());
+ return info() ? g_base_info_get_name(info()) : type_name();
}
private:
@@ -739,9 +737,10 @@ template <class Base, class Prototype, class Instance,
typename Info = GIObjectInfo>
class GIWrapperPrototype : public Base {
protected:
- // m_info may be null in the case of JS-defined types, although not all
- // subclasses will allow this. Object and Interface allow it in any case.
- // Use the method Base::is_custom_js_class() for clarity.
+ // m_info may be null in the case of JS-defined types, or internal types
+ // not exposed through introspection, such as GLocalFile. Not all subclasses
+ // of GIWrapperPrototype support this. Object and Interface support it in
+ // any case.
Info* m_info;
GType m_gtype;
@@ -856,10 +855,10 @@ class GIWrapperPrototype : public Base {
JS::MutableHandleObject prototype) {
// The GI namespace is only used to set the JSClass->name field (exposed
// by Object.prototype.toString, for example). We can safely set
- // "unknown" if this is a custom JS class with no GI namespace, as in
- // that case the name is already globally unique (it's a GType name).
- const char* gi_namespace =
- Base::is_custom_js_class() ? "unknown" : Base::ns();
+ // "unknown" if this is a custom or internal JS class with no GI
+ // namespace, as in that case the name is already globally unique (it's
+ // a GType name).
+ const char* gi_namespace = Base::info() ? Base::ns() : "unknown";
unsigned nargs = static_cast<Prototype*>(this)->constructor_nargs();
@@ -892,6 +891,8 @@ class GIWrapperPrototype : public Base {
*/
GJS_JSAPI_RETURN_CONVENTION
bool define_static_methods(JSContext* cx, JS::HandleObject constructor) {
+ if (!info())
+ return true; // no introspection means no methods to define
return gjs_define_static_methods<Prototype::info_type_tag>(
cx, constructor, m_gtype, m_info);
}
@@ -963,10 +964,8 @@ class GIWrapperPrototype : public Base {
return nullptr;
}
- if (!priv->is_custom_js_class()) {
- if (!priv->define_static_methods(cx, constructor))
- return nullptr;
- }
+ if (!priv->define_static_methods(cx, constructor))
+ return nullptr;
return priv;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]