summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/duk-libdom-dictionary.c2
-rw-r--r--src/duk-libdom-interface.c102
-rw-r--r--src/ir.c68
-rw-r--r--src/ir.h2
-rw-r--r--src/options.h3
5 files changed, 155 insertions, 22 deletions
diff --git a/src/duk-libdom-dictionary.c b/src/duk-libdom-dictionary.c
index 65a140a..09e4379 100644
--- a/src/duk-libdom-dictionary.c
+++ b/src/duk-libdom-dictionary.c
@@ -267,7 +267,7 @@ output_member_acessor(FILE* outf,
default:
WARN(WARNING_UNIMPLEMENTED,
- "Dictionary %s:%s unhandled type (%d)\n",
+ "Dictionary %s:%s unhandled type (%d)",
dictionarye->name,
membere->name,
*argument_type);
diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c
index 0fef35b..96e41ad 100644
--- a/src/duk-libdom-interface.c
+++ b/src/duk-libdom-interface.c
@@ -619,7 +619,8 @@ output_prototype_attribute(FILE *outf,
struct ir_entry *interfacee,
struct ir_attribute_entry *attributee)
{
- if (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
+ if ((attributee->putforwards == NULL) &&
+ (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY)) {
return output_populate_ro_property(outf,
interfacee->class_name,
attributee->name);
@@ -1193,28 +1194,29 @@ output_interface_operations(FILE* outf, struct ir_entry *ife)
return res;
}
+
/**
- * Generate class property getter/setter for a single attribute
+ * Generate class property setter for a single attribute
*/
static int
-output_interface_attribute(FILE* outf,
- struct ir_entry *interfacee,
- struct ir_attribute_entry *atributee)
+output_attribute_setter(FILE* outf,
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *atributee)
{
int cdatac;
- /* getter definition */
+ /* setter definition */
fprintf(outf,
- "static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n",
+ "static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n",
DLPFX, interfacee->class_name, atributee->name);
fprintf(outf,"{\n");
output_get_method_private(outf, interfacee->class_name);
- cdatac = output_ccode(outf, atributee->getter);
+ cdatac = output_ccode(outf, atributee->setter);
if (cdatac == 0) {
WARN(WARNING_UNIMPLEMENTED,
- "Unimplemented: getter %s::%s();",
+ "Unimplemented: setter %s::%s();",
interfacee->name, atributee->name);
/* no implementation so generate default */
@@ -1223,23 +1225,80 @@ output_interface_attribute(FILE* outf,
fprintf(outf, "}\n\n");
- /* readonly attributes have no setter */
- if (atributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
- return 0;
+ return 0;
+}
+
+/**
+ * Generate class property setter for a putforwards attribute
+ */
+static int
+output_putforwards_setter(FILE* outf,
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *atributee)
+{
+ /* use explicit implementation in bindings if present */
+ if (atributee->setter != NULL) {
+ return output_attribute_setter(outf, interfacee, atributee);
}
- /* setter definition */
+ /* generate autogenerated putforwards */
+
fprintf(outf,
"static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n",
DLPFX, interfacee->class_name, atributee->name);
fprintf(outf,"{\n");
+ fprintf(outf,"\tduk_ret_t get_ret;\n\n");
+
+ fprintf(outf,
+ "\tget_ret = %s_%s_%s_getter(ctx);\n",
+ DLPFX, interfacee->class_name, atributee->name);
+
+ fprintf(outf,
+ "\tif (get_ret != 1) {\n"
+ "\t\treturn 0;\n"
+ "\t}\n\n"
+ "\t/* parameter attribute */\n\n"
+ "\tduk_swap(ctx, 0, 1);\n"
+ "\t/* attribute parameter */\n\n"
+ "\t/* call the putforward */\n");
+
+ fprintf(outf,
+ "\tduk_put_prop_string(ctx, 0, \"%s\");\n\n",
+ atributee->putforwards);
+
+ fprintf(outf,
+ "\tduk_pop(ctx);\n\n"
+ "\treturn 0;\n");
+
+ fprintf(outf, "}\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate class property getter/setter for a single attribute
+ */
+static int
+output_interface_attribute(FILE* outf,
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *atributee)
+{
+ int cdatac;
+ int res = 0;
+
+ /* getter definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, atributee->name);
+ fprintf(outf,"{\n");
+
output_get_method_private(outf, interfacee->class_name);
- cdatac = output_ccode(outf, atributee->setter);
+ cdatac = output_ccode(outf, atributee->getter);
if (cdatac == 0) {
WARN(WARNING_UNIMPLEMENTED,
- "Unimplemented: setter %s::%s();",
+ "Unimplemented: getter %s::%s();",
interfacee->name, atributee->name);
/* no implementation so generate default */
@@ -1248,7 +1307,18 @@ output_interface_attribute(FILE* outf,
fprintf(outf, "}\n\n");
- return 0;
+ if (atributee->putforwards != NULL) {
+ res = output_putforwards_setter(outf, interfacee, atributee);
+ } else {
+ /* readonly attributes have no setter */
+ if (atributee->modifier != WEBIDL_TYPE_MODIFIER_READONLY) {
+ res = output_attribute_setter(outf,
+ interfacee,
+ atributee);
+ }
+ }
+
+ return res;
}
/**
diff --git a/src/ir.c b/src/ir.c
index b3631f4..6dc2d2a 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -377,6 +377,56 @@ operation_map_new(struct webidl_node *interface,
return 0;
}
+/**
+ * get the value of an extended attribute key/value item
+ */
+static char *
+get_extended_value(struct webidl_node *node, const char *key)
+{
+ char *ident;
+ struct webidl_node *ext_attr;
+ struct webidl_node *elem;
+
+ /* walk each extended attribute */
+ ext_attr = webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE);
+ while (ext_attr != NULL) {
+
+ elem = webidl_node_find_type(
+ webidl_node_getnode(ext_attr),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT);
+ ident = webidl_node_gettext(elem);
+
+ if ((ident != NULL) && (strcmp(ident, key) == 0)) {
+ /* first identifier matches */
+
+ elem = webidl_node_find_type(
+ webidl_node_getnode(ext_attr),
+ elem,
+ WEBIDL_NODE_TYPE_IDENT);
+ ident = webidl_node_gettext(elem);
+
+ if ((ident != NULL) && (*ident == '=')) {
+ return webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(ext_attr),
+ elem,
+ WEBIDL_NODE_TYPE_IDENT));
+ }
+ }
+
+ ext_attr = webidl_node_find_type(
+ webidl_node_getnode(node),
+ ext_attr,
+ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE);
+ }
+
+ return NULL;
+}
+
static int
attribute_map_new(struct webidl_node *interface,
struct genbind_node *class,
@@ -399,8 +449,7 @@ attribute_map_new(struct webidl_node *interface,
return 0;
}
- attributev = calloc(attributec,
- sizeof(struct ir_attribute_entry));
+ attributev = calloc(attributec, sizeof(struct ir_attribute_entry));
if (attributev == NULL) {
return -1;
};
@@ -436,7 +485,7 @@ attribute_map_new(struct webidl_node *interface,
GENBIND_METHOD_TYPE_GETTER,
cure->name);
- /* check fo readonly attributes */
+ /* check for readonly attributes */
modifier = (enum webidl_type_modifier *)webidl_node_getint(
webidl_node_find_type(
webidl_node_getnode(at_node),
@@ -454,9 +503,20 @@ attribute_map_new(struct webidl_node *interface,
cure->name);
}
- cure++;
+ /* check for putforwards extended attribute */
+ cure->putforwards = get_extended_value(at_node,
+ "PutForwards");
+
+ if ((cure->putforwards != NULL) &&
+ (cure->modifier != WEBIDL_TYPE_MODIFIER_READONLY)) {
+ WARN(WARNING_WEBIDL,
+ "putforwards on a writable attribute (%s) is prohibited",
+ cure->name);
+ }
/* move to next attribute */
+ cure++;
+
at_node = webidl_node_find_type(
webidl_node_getnode(list_node),
at_node,
diff --git a/src/ir.h b/src/ir.h
index 1092fab..ecedc95 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -53,6 +53,8 @@ struct ir_attribute_entry {
struct webidl_node *node; /**< AST attribute node */
enum webidl_type_modifier modifier;
+ const char *putforwards;
+
struct genbind_node *getter; /**< getter from binding */
struct genbind_node *setter; /**< getter from binding */
};
diff --git a/src/options.h b/src/options.h
index 5b7d73d..d452c17 100644
--- a/src/options.h
+++ b/src/options.h
@@ -28,9 +28,10 @@ extern struct options *options;
enum opt_warnings {
WARNING_UNIMPLEMENTED = 1,
WARNING_DUPLICATED = 2,
+ WARNING_WEBIDL = 4,
};
-#define WARNING_ALL (WARNING_UNIMPLEMENTED | WARNING_DUPLICATED)
+#define WARNING_ALL (WARNING_UNIMPLEMENTED | WARNING_DUPLICATED | WARNING_WEBIDL)
#define WARN(flags, msg, args...) do { \
if ((options->warnings & flags) != 0) { \