From ac6ae0a7b545dbf3391760cfe9e6b86ce0c579db Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Sep 2015 14:29:00 +0100 Subject: Implement putforwards processing. interface attributes with the putforwards extended attribute call the setter specified in that extended attribute. The WebIDL is supposed to ensure the attribute is readonly before allowing a putforwards but we only warn about this as there are several examples where readonly is omitted. --- src/duk-libdom-interface.c | 102 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 16 deletions(-) (limited to 'src/duk-libdom-interface.c') 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; } /** -- cgit v1.2.3