summaryrefslogtreecommitdiff
path: root/src/jsapi-libdom.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2012-10-31 01:20:20 +0000
committerVincent Sanders <vince@kyllikki.org>2012-10-31 01:20:20 +0000
commit65e49e23019a97d51702077c82613c6c26e84033 (patch)
treef21ba90ba9dc08826ef687f9bd148e6345fd673a /src/jsapi-libdom.c
parent26bbe37c6f0b99f23736380ba55f156f22bdaf06 (diff)
downloadnsgenbind-65e49e23019a97d51702077c82613c6c26e84033.tar.gz
nsgenbind-65e49e23019a97d51702077c82613c6c26e84033.tar.bz2
implement the "implements" webidl directive
Diffstat (limited to 'src/jsapi-libdom.c')
-rw-r--r--src/jsapi-libdom.c265
1 files changed, 118 insertions, 147 deletions
diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c
index 36ed6b6..5a73f5e 100644
--- a/src/jsapi-libdom.c
+++ b/src/jsapi-libdom.c
@@ -17,7 +17,7 @@
#include "webidl-ast.h"
#include "jsapi-libdom.h"
-#define HDR_COMMENT_SEP "\n * "
+#define HDR_COMMENT_SEP "\n * \n * "
#define HDR_COMMENT_PREABLE "Generated by nsgenbind "
@@ -80,85 +80,6 @@ static int webidl_hdrcomment_cb(struct genbind_node *node, void *ctx)
return 0;
}
-
-
-
-static int webidl_func_spec_cb(struct webidl_node *node, void *ctx)
-{
- struct binding *binding = ctx;
- struct webidl_node *ident_node;
-
- ident_node = webidl_node_find(webidl_node_getnode(node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_IDENT);
-
- if (ident_node == NULL) {
- /* operation without identifier - must have special keyword
- * http://www.w3.org/TR/WebIDL/#idl-operations
- */
- } else {
- fprintf(binding->outfile,
- " JSAPI_FS(%s, 0, 0),\n",
- webidl_node_gettext(ident_node));
- }
- return 0;
-}
-
-static int
-generate_function_spec(struct binding *binding, const char *interface)
-{
- struct webidl_node *interface_node;
- struct webidl_node *members_node;
- struct webidl_node *inherit_node;
-
- /* find interface in webidl with correct ident attached */
- interface_node = webidl_node_find_type_ident(binding->wi_ast,
- WEBIDL_NODE_TYPE_INTERFACE,
- interface);
-
- if (interface_node == NULL) {
- fprintf(stderr,
- "Unable to find interface %s in loaded WebIDL\n",
- interface);
- return -1;
- }
-
- members_node = webidl_node_find(webidl_node_getnode(interface_node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_LIST);
- while (members_node != NULL) {
-
- fprintf(binding->outfile," /**** %s ****/\n", interface);
-
- /* for each function emit a JSAPI_FS()*/
- webidl_node_for_each_type(webidl_node_getnode(members_node),
- WEBIDL_NODE_TYPE_OPERATION,
- webidl_func_spec_cb,
- binding);
-
- members_node = webidl_node_find(webidl_node_getnode(interface_node),
- members_node,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_LIST);
- }
-
- /* check for inherited nodes and insert them too */
- inherit_node = webidl_node_find(webidl_node_getnode(interface_node),
- NULL,
- webidl_cmp_node_type,
- (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
-
- if (inherit_node != NULL) {
- return generate_function_spec(binding,
- webidl_node_gettext(inherit_node));
- }
-
- return 0;
-}
-
-
static int webidl_private_cb(struct genbind_node *node, void *ctx)
{
struct binding *binding = ctx;
@@ -237,18 +158,20 @@ output_class_operations(struct binding *binding)
{
int res = 0;
- /* finalize */
- fprintf(binding->outfile,
- "static void jsclass_finalize(JSContext *cx, JSObject *obj)\n"
- "{"
- "\tstruct jsclass_private *private;\n"
- "\n"
- "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n"
- "\tif (private != NULL) {\n"
- "\t\tfree(private);\n"
- "\t}\n"
- "}\n\n",
- binding->interface);
+ if (binding->has_private) {
+ /* finalizer only required if there is a private to free */
+ fprintf(binding->outfile,
+ "static void jsclass_finalize(JSContext *cx, JSObject *obj)\n"
+ "{"
+ "\tstruct jsclass_private *private;\n"
+ "\n"
+ "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n"
+ "\tif (private != NULL) {\n"
+ "\t\tfree(private);\n"
+ "\t}\n"
+ "}\n\n",
+ binding->interface);
+ }
/* resolve */
fprintf(binding->outfile,
@@ -351,18 +274,22 @@ output_class_new(struct binding *binding)
fprintf(binding->outfile,
")\n"
"{\n"
- "\tJSObject *newobject;\n"
- "\tstruct jsclass_private *private;\n"
- "\n"
- "\tprivate = malloc(sizeof(struct jsclass_private));\n"
- "\tif (private == NULL) {\n"
- "\t\treturn NULL;\n"
- "\t}\n");
+ "\tJSObject *newobject;\n");
- genbind_node_for_each_type(genbind_node_getnode(binding_node),
- GENBIND_NODE_TYPE_BINDING_PRIVATE,
- webidl_private_assign_cb,
- binding);
+ if (binding->has_private) {
+ fprintf(binding->outfile,
+ "\tstruct jsclass_private *private;\n"
+ "\n"
+ "\tprivate = malloc(sizeof(struct jsclass_private));\n"
+ "\tif (private == NULL) {\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
+
+ genbind_node_for_each_type(genbind_node_getnode(binding_node),
+ GENBIND_NODE_TYPE_BINDING_PRIVATE,
+ webidl_private_assign_cb,
+ binding);
+ }
api_node = genbind_node_find_type_ident(binding->gb_ast,
NULL,
@@ -374,22 +301,26 @@ output_class_new(struct binding *binding)
} else {
fprintf(binding->outfile,
"\n"
- "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n"
+ "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n",
+ binding->interface);
+ }
+
+ if (binding->has_private) {
+ fprintf(binding->outfile,
"\tif (newobject == NULL) {\n"
"\t\tfree(private);\n"
"\t\treturn NULL;\n"
- "\t}\n",
- binding->interface);
+ "\t}\n"
+ "\n"
+ "\t/* attach private pointer */\n"
+ "\tif (JS_SetPrivate(cx, newobject, private) != JS_TRUE) {\n"
+ "\t\tfree(private);\n"
+ "\t\treturn NULL;\n"
+ "\t}\n");
}
fprintf(binding->outfile,
"\n"
- "\t/* attach private pointer */\n"
- "\tif (JS_SetPrivate(cx, newobject, private) != JS_TRUE) {\n"
- "\t\tfree(private);\n"
- "\t\treturn NULL;\n"
- "\t}\n"
- "\n"
"\treturn newobject;\n"
"}\n");
@@ -398,48 +329,62 @@ output_class_new(struct binding *binding)
}
-static int
-output_function_spec(struct binding *binding)
-{
- int res;
- fprintf(binding->outfile,
- "static JSFunctionSpec jsclass_functions[] = {\n");
- res = generate_function_spec(binding, binding->interface);
- fprintf(binding->outfile, " JSAPI_FS_END\n};\n\n");
+static int
+output_jsclass(struct binding *binding)
+{
+ if (binding->has_private) {
- return res;
-}
+ /* forward declare the resolver and finalizer */
+ fprintf(binding->outfile,
+ "static void jsclass_finalize(JSContext *cx, JSObject *obj);\n");
+
+ fprintf(binding->outfile,
+ "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n");
+ /* output the class */
+ fprintf(binding->outfile,
+ "JSClass JSClass_%1$s = {\n"
+ " \"%1$s\",\n"
+ " JSCLASS_NEW_RESOLVE | JSCLASS_HAS_PRIVATE,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_StrictPropertyStub,\n"
+ " JS_EnumerateStub,\n"
+ " (JSResolveOp)jsclass_resolve,\n"
+ " JS_ConvertStub,\n"
+ " jsclass_finalize,\n"
+ " JSCLASS_NO_OPTIONAL_MEMBERS\n"
+ "};\n\n",
+ binding->interface);
+ } else {
+ /* forward declare the resolver */
+
+ fprintf(binding->outfile,
+ "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n");
-static int
-output_jsclass(struct binding *binding)
-{
- /* forward declare the resolver and finalizer */
- fprintf(binding->outfile,
- "static void jsclass_finalize(JSContext *cx, JSObject *obj);\n");
- fprintf(binding->outfile,
- "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n");
- /* output the class */
- fprintf(binding->outfile,
- "JSClass JSClass_%1$s = {\n"
- " \"%1$s\",\n"
- " JSCLASS_NEW_RESOLVE | JSCLASS_HAS_PRIVATE,\n"
- " JS_PropertyStub,\n"
- " JS_PropertyStub,\n"
- " JS_PropertyStub,\n"
- " JS_StrictPropertyStub,\n"
- " JS_EnumerateStub,\n"
- " (JSResolveOp)jsclass_resolve,\n"
- " JS_ConvertStub,\n"
- " jsclass_finalize,\n"
- " JSCLASS_NO_OPTIONAL_MEMBERS\n"
- "};\n\n",
- binding->interface);
+ /* output the class */
+ fprintf(binding->outfile,
+ "JSClass JSClass_%1$s = {\n"
+ " \"%1$s\",\n"
+ " JSCLASS_NEW_RESOLVE,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_PropertyStub,\n"
+ " JS_StrictPropertyStub,\n"
+ " JS_EnumerateStub,\n"
+ " (JSResolveOp)jsclass_resolve,\n"
+ " JS_ConvertStub,\n"
+ " JS_FinalizeStub,\n"
+ " JSCLASS_NO_OPTIONAL_MEMBERS\n"
+ "};\n\n",
+ binding->interface);
+ }
return 0;
}
@@ -449,6 +394,10 @@ output_private_declaration(struct binding *binding)
struct genbind_node *binding_node;
struct genbind_node *type_node;
+ if (!binding->has_private) {
+ return 0;
+ }
+
binding_node = genbind_node_find(binding->gb_ast,
NULL,
genbind_cmp_node_type,
@@ -512,6 +461,28 @@ output_header_comments(struct binding *binding)
return 0;
}
+static bool
+binding_has_private(struct genbind_node *binding_node)
+{
+ struct genbind_node *node;
+
+ node = genbind_node_find_type(genbind_node_getnode(binding_node),
+ NULL,
+ GENBIND_NODE_TYPE_BINDING_PRIVATE);
+
+ if (node != NULL) {
+ return true;
+ }
+
+ node = genbind_node_find_type(genbind_node_getnode(binding_node),
+ NULL,
+ GENBIND_NODE_TYPE_BINDING_INTERNAL);
+ if (node != NULL) {
+ return true;
+ }
+ return false;
+}
+
static struct binding *
binding_new(char *outfilename, struct genbind_node *genbind_ast)
{
@@ -571,7 +542,7 @@ binding_new(char *outfilename, struct genbind_node *genbind_ast)
nb->name = genbind_node_gettext(ident_node);
nb->interface = genbind_node_gettext(interface_node);
nb->outfile = outfile;
-
+ nb->has_private = binding_has_private(binding_node);
return nb;
}