[gjs] GParamSpec: implement methods



commit a393b31ff65cbc62a3f9d3baa7def1fabdc0a399
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Wed Feb 26 21:45:56 2014 +0100

    GParamSpec: implement methods
    
    Methods are definitely expected for GParamSpec classes, even
    more than fields, and are easy to implement.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725282

 gi/function.cpp                     |   21 +++++++-
 gi/param.cpp                        |   89 +++++++++++++++++++++++++++++++---
 installed-tests/js/testParamSpec.js |    8 +++
 3 files changed, 108 insertions(+), 10 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index a96b681..859ea44 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -30,6 +30,9 @@
 #include "boxed.h"
 #include "union.h"
 #include "gerror.h"
+#include "closure.h"
+#include "gtype.h"
+#include "param.h"
 #include <gjs/gjs-module.h>
 #include <gjs/compat.h>
 #include <gjs/jsapi-private.h>
@@ -570,11 +573,25 @@ gjs_fill_method_instance (JSContext  *context,
 
     case GI_INFO_TYPE_OBJECT:
     case GI_INFO_TYPE_INTERFACE:
-        if (gjs_typecheck_is_object(context, obj, JS_FALSE)) {
+        if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
             if (!gjs_typecheck_object(context, obj, gtype, JS_TRUE))
                 return JS_FALSE;
             out_arg->v_pointer = gjs_g_object_from_object(context, obj);
-        } else if (gjs_typecheck_is_fundamental(context, obj, JS_FALSE)) {
+        } else if (g_type_is_a(gtype, G_TYPE_PARAM)) {
+            if (!gjs_typecheck_param(context, obj, G_TYPE_PARAM, JS_TRUE))
+                return JS_FALSE;
+            out_arg->v_pointer = gjs_g_param_from_param(context, obj);
+        } else if (G_TYPE_IS_INTERFACE(gtype)) {
+            if (gjs_typecheck_is_object(context, obj, JS_FALSE)) {
+                if (!gjs_typecheck_object(context, obj, gtype, JS_TRUE))
+                    return JS_FALSE;
+                out_arg->v_pointer = gjs_g_object_from_object(context, obj);
+            } else {
+                if (!gjs_typecheck_fundamental(context, obj, gtype, JS_TRUE))
+                    return JS_FALSE;
+                out_arg->v_pointer = gjs_g_fundamental_from_object(context, obj);
+            }
+        } else if (G_TYPE_IS_INSTANTIATABLE(gtype)) {
             if (!gjs_typecheck_fundamental(context, obj, gtype, JS_TRUE))
                 return JS_FALSE;
             out_arg->v_pointer = gjs_g_fundamental_from_object(context, obj);
diff --git a/gi/param.cpp b/gi/param.cpp
index 59c4188..0f3c18b 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -30,6 +30,7 @@
 #include "object.h"
 #include "repo.h"
 #include "gtype.h"
+#include "function.h"
 #include <gjs/gjs-module.h>
 #include <gjs/compat.h>
 
@@ -43,6 +44,79 @@ extern struct JSClass gjs_param_class;
 
 GJS_DEFINE_PRIV_FROM_JS(Param, gjs_param_class)
 
+/*
+ * Like JSResolveOp, but flags provide contextual information as follows:
+ *
+ *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
+ *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
+ *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
+ *  JSRESOLVE_DECLARING   var, const, or object prolog declaration opcode
+ *  JSRESOLVE_CLASSNAME   class name used when constructing
+ *
+ * The *objp out parameter, on success, should be null to indicate that id
+ * was not resolved; and non-null, referring to obj or one of its prototypes,
+ * if id was resolved.
+ */
+static JSBool
+param_new_resolve(JSContext *context,
+                  JSObject **obj,
+                  jsid      *id,
+                  unsigned   flags,
+                  JSObject **objp)
+{
+    GIObjectInfo *info = NULL;
+    GIFunctionInfo *method_info;
+    Param *priv;
+    char *name;
+    JSBool ret = JS_FALSE;
+
+    *objp = NULL;
+
+    if (!gjs_get_string_id(context, *id, &name))
+        return JS_TRUE; /* not resolved, but no error */
+
+    priv = priv_from_js(context, *obj);
+
+    if (priv != NULL) {
+        /* instance, not prototype */
+        ret = JS_TRUE;
+        goto out;
+    }
+
+    info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM);
+    method_info = g_object_info_find_method(info, name);
+
+    if (method_info == NULL) {
+        ret = JS_TRUE;
+        goto out;
+    }
+#if GJS_VERBOSE_ENABLE_GI_USAGE
+    _gjs_log_info_usage((GIBaseInfo*) method_info);
+#endif
+
+    gjs_debug(GJS_DEBUG_GOBJECT,
+              "Defining method %s in prototype for GObject.ParamSpec",
+              g_base_info_get_name( (GIBaseInfo*) method_info));
+
+    if (gjs_define_function(context, *obj, G_TYPE_PARAM, method_info) == NULL) {
+        g_base_info_unref( (GIBaseInfo*) method_info);
+        goto out;
+    }
+
+    *objp = *obj; /* we defined the prop in obj */
+
+    g_base_info_unref( (GIBaseInfo*) method_info);
+
+    ret = JS_TRUE;
+ out:
+    g_free(name);
+    if (info != NULL)
+        g_base_info_unref( (GIBaseInfo*)info);
+
+    return ret;
+}
+
+
 static GIFieldInfo *
 find_field_info(GIObjectInfo *info,
                 gchar        *name)
@@ -82,16 +156,15 @@ param_get_prop(JSContext              *context,
     GITypeInfo *type_info = NULL;
     GIArgument arg;
 
-    if (!gjs_get_string_id(context, id, &name))
-        return JS_TRUE; /* not something we affect, but no error */
-
     priv = priv_from_js(context, obj);
-
     if (priv == NULL) {
-        g_free(name);
-        return JS_FALSE; /* wrong class */
+        /* prototype */
+        return JS_TRUE;
     }
 
+    if (!gjs_get_string_id(context, id, &name))
+        return JS_TRUE; /* not something we affect, but no error */
+
     success = JS_FALSE;
     pspec = priv->gparam;
 
@@ -115,7 +188,6 @@ param_get_prop(JSContext              *context,
     }
 
     if (field_info == NULL) {
-        value_p.set(JSVAL_VOID);
         success = JS_TRUE;
         goto out;
     }
@@ -186,13 +258,14 @@ param_finalize(JSFreeOp *fop,
 struct JSClass gjs_param_class = {
     "GObject_ParamSpec",
     JSCLASS_HAS_PRIVATE |
+    JSCLASS_NEW_RESOLVE |
     JSCLASS_BACKGROUND_FINALIZE,
     JS_PropertyStub,
     JS_DeletePropertyStub,
     param_get_prop,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
-    JS_ResolveStub,
+    (JSResolveOp) param_new_resolve,
     JS_ConvertStub,
     param_finalize,
     NULL,
diff --git a/installed-tests/js/testParamSpec.js b/installed-tests/js/testParamSpec.js
index ca7b088..1b7013c 100644
--- a/installed-tests/js/testParamSpec.js
+++ b/installed-tests/js/testParamSpec.js
@@ -91,5 +91,13 @@ function testFlagsParamSpec() {
     JSUnit.assertEquals(Regress.TestFlags.FLAG2, flagsSpec.default_value);
 }
 
+function testParamSpecMethod() {
+    let objectSpec = GObject.ParamSpec.object(name, nick, blurb, flags, GObject.Object);
+
+    JSUnit.assertEquals(name, objectSpec.get_name());
+    JSUnit.assertEquals(nick, objectSpec.get_nick());
+    JSUnit.assertEquals(blurb, objectSpec.get_blurb());
+}
+
 JSUnit.gjstestRun(this, JSUnit.setUp, JSUnit.tearDown);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]