From c80955dcc6b663c250a1f2552b626770fbd46a94 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 28 Sep 2015 07:59:50 +0100 Subject: annotates binding AST with source linenumber and file Uses annotated AST to put line directives in the generated source so any code errors in the binding can be easily located. --- src/duk-libdom-common.c | 23 +++++++++++++++++++++++ src/duk-libdom-interface.c | 14 ++++---------- src/duk-libdom.h | 13 +++++++++++++ src/nsgenbind-ast.c | 8 ++++++++ src/nsgenbind-ast.h | 3 +++ src/nsgenbind-parser.y | 18 ++++++++++++++---- 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/duk-libdom-common.c b/src/duk-libdom-common.c index fc62863..fb97fe3 100644 --- a/src/duk-libdom-common.c +++ b/src/duk-libdom-common.c @@ -57,6 +57,29 @@ int output_cdata(FILE* outf, return res; } +/* exported interface documented in duk-libdom.h */ +int output_ccode(FILE* outf, struct genbind_node *node) +{ + int *line; + char *filename; + + line = genbind_node_getint( + genbind_node_find_type( + genbind_node_getnode(node), + NULL, GENBIND_NODE_TYPE_LINE)); + + filename = genbind_node_gettext( + genbind_node_find_type( + genbind_node_getnode(node), + NULL, GENBIND_NODE_TYPE_FILE)); + + if ((line != NULL) && (filename != NULL)) { + fprintf(outf, "#line %d \"%s\"\n", *line, filename); + } + + return output_cdata(outf, node, GENBIND_NODE_TYPE_CDATA); +} + /* exported interface documented in duk-libdom.h */ int output_tool_prologue(FILE* outf) { diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c index 997cb9a..0fef35b 100644 --- a/src/duk-libdom-interface.c +++ b/src/duk-libdom-interface.c @@ -517,7 +517,7 @@ output_interface_init(FILE* outf, } /* output the initaliser code from the binding */ - output_cdata(outf, init_node, GENBIND_NODE_TYPE_CDATA); + output_ccode(outf, init_node); fprintf(outf, "}\n\n"); @@ -1157,10 +1157,7 @@ output_interface_operation(FILE* outf, output_get_method_private(outf, interfacee->class_name); - cdatac = output_cdata(outf, - operatione->method, - GENBIND_NODE_TYPE_CDATA); - + cdatac = output_ccode(outf, operatione->method); if (cdatac == 0) { /* no implementation so generate default */ WARN(WARNING_UNIMPLEMENTED, @@ -1214,8 +1211,7 @@ output_interface_attribute(FILE* outf, output_get_method_private(outf, interfacee->class_name); - cdatac = output_cdata(outf, atributee->getter, GENBIND_NODE_TYPE_CDATA); - + cdatac = output_ccode(outf, atributee->getter); if (cdatac == 0) { WARN(WARNING_UNIMPLEMENTED, "Unimplemented: getter %s::%s();", @@ -1240,8 +1236,7 @@ output_interface_attribute(FILE* outf, output_get_method_private(outf, interfacee->class_name); - cdatac = output_cdata(outf, atributee->setter, GENBIND_NODE_TYPE_CDATA); - + cdatac = output_ccode(outf, atributee->setter); if (cdatac == 0) { WARN(WARNING_UNIMPLEMENTED, "Unimplemented: setter %s::%s();", @@ -1251,7 +1246,6 @@ output_interface_attribute(FILE* outf, fprintf(outf,"\treturn 0;\n"); } - fprintf(outf, "}\n\n"); return 0; diff --git a/src/duk-libdom.h b/src/duk-libdom.h index b9eeea3..dd27420 100644 --- a/src/duk-libdom.h +++ b/src/duk-libdom.h @@ -56,6 +56,19 @@ int output_tool_prologue(FILE* outf); */ int output_cdata(FILE* outf, struct genbind_node *node, enum genbind_node_type nodetype); + +/** + * output c code with line directives if possible. + * + * used for any cdata sections + * + * \param outf The file handle to write output. + * \param node The node to search. + * \param nodetype the type of child node to search for. + * \return The number of nodes written or 0 for none. + */ +int output_ccode(FILE* outf, struct genbind_node *node); + /** * output character data of method node of given type. * diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c index 749d3e8..9be8bc7 100644 --- a/src/nsgenbind-ast.c +++ b/src/nsgenbind-ast.c @@ -341,6 +341,7 @@ char *genbind_node_gettext(struct genbind_node *node) case GENBIND_NODE_TYPE_IDENT: case GENBIND_NODE_TYPE_NAME: case GENBIND_NODE_TYPE_CDATA: + case GENBIND_NODE_TYPE_FILE: return node->r.text; default: @@ -377,6 +378,7 @@ int *genbind_node_getint(struct genbind_node *node) if (node != NULL) { switch(node->type) { case GENBIND_NODE_TYPE_METHOD_TYPE: + case GENBIND_NODE_TYPE_LINE: case GENBIND_NODE_TYPE_MODIFIER: return &node->r.number; @@ -408,6 +410,12 @@ static const char *genbind_node_type_to_str(enum genbind_node_type type) case GENBIND_NODE_TYPE_NAME: return "TypeName"; + case GENBIND_NODE_TYPE_LINE: + return "Linenumber"; + + case GENBIND_NODE_TYPE_FILE: + return "Filename"; + case GENBIND_NODE_TYPE_PRIVATE: return "Private"; diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h index b130db2..49db23b 100644 --- a/src/nsgenbind-ast.h +++ b/src/nsgenbind-ast.h @@ -16,6 +16,8 @@ enum genbind_node_type { GENBIND_NODE_TYPE_MODIFIER, /**< node modifier */ GENBIND_NODE_TYPE_CDATA, /**< verbatim block of character data */ GENBIND_NODE_TYPE_STRING, /**< text string */ + GENBIND_NODE_TYPE_LINE, /**< linenumber */ + GENBIND_NODE_TYPE_FILE, /**< file name */ GENBIND_NODE_TYPE_BINDING, /**< Binding */ GENBIND_NODE_TYPE_WEBIDL, @@ -28,6 +30,7 @@ enum genbind_node_type { GENBIND_NODE_TYPE_METHOD, /**< binding method */ GENBIND_NODE_TYPE_METHOD_TYPE, /**< binding method type */ + GENBIND_NODE_TYPE_PARAMETER, /**< method parameter */ }; diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y index b52d0d0..a3e5609 100644 --- a/src/nsgenbind-parser.y +++ b/src/nsgenbind-parser.y @@ -104,12 +104,15 @@ static struct genbind_node * add_method(struct genbind_node **genbind_ast, long methodtype, struct genbind_node *declarator, - char *cdata) + char *cdata, + int lineno, + char *filename) { struct genbind_node *res_node; struct genbind_node *method_node; struct genbind_node *class_node; struct genbind_node *cdata_node; + struct genbind_node *location_node; char *class_name; /* extract the class name from the declarator */ @@ -131,11 +134,18 @@ add_method(struct genbind_node **genbind_ast, cdata); } + + location_node = genbind_new_node(GENBIND_NODE_TYPE_FILE, + genbind_new_node(GENBIND_NODE_TYPE_LINE, + cdata_node, + (void *)lineno), + strdup(filename)); + /* generate method node */ method_node = genbind_new_node(GENBIND_NODE_TYPE_METHOD, NULL, genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE, - cdata_node, + location_node, (void *)methodtype)); class_node = genbind_node_find_type_ident(*genbind_ast, @@ -396,12 +406,12 @@ ParameterList: Method: MethodType MethodDeclarator CBlock { - $$ = add_method(genbind_ast, $1, $2, $3); + $$ = add_method(genbind_ast, $1, $2, $3, @1.first_line, @1.filename); } | MethodType MethodDeclarator ';' { - $$ = add_method(genbind_ast, $1, $2, NULL); + $$ = add_method(genbind_ast, $1, $2, NULL, @1.first_line, @1.filename); } ; -- cgit v1.2.1