// Write a description of the given entity to its own type file. // The containing package is handed in to save looking it up again. static void doc_entity(docgen_t* docgen, ast_t* ast, ast_t* package) { assert(docgen != NULL); assert(docgen->index_file != NULL); assert(docgen->type_file == NULL); assert(ast != NULL); assert(package != NULL); // First open a file size_t tqfn_len; char* tqfn = write_tqfn(ast, NULL, &tqfn_len); docgen->type_file = doc_open_file(docgen, true, tqfn, ".md"); if(docgen->type_file == NULL) return; // Add reference to new file to index file AST_GET_CHILDREN(ast, id, tparams, cap, provides, members, c_api, doc); const char* name = ast_name(id); assert(name != NULL); fprintf(docgen->index_file, " - %s %s: \"%s.md\"\n", ast_get_print(ast), name, tqfn); pool_free_size(tqfn_len, tqfn); // Now we can write the actual documentation for the entity fprintf(docgen->type_file, "%s %s", ast_get_print(ast), name); doc_type_params(docgen, tparams); doc_type_list(docgen, provides, " is ", ", ", ""); fprintf(docgen->type_file, "\n\nIn package \"%s\".\n\n", package_qualified_name(package)); fprintf(docgen->type_file, "%s", (name[0] == '_') ? "Private" : "Public"); const char* cap_text = doc_get_cap(cap); if(cap_text != NULL) fprintf(docgen->type_file, ", default capability %s", cap_text); fprintf(docgen->type_file, ".\n\n"); if(ast_id(c_api) == TK_AT) fprintf(docgen->type_file, "May be called from C.\n"); if(ast_id(doc) != TK_NONE) fprintf(docgen->type_file, "%s\n\n", ast_name(doc)); else fprintf(docgen->type_file, "No doc string provided.\n\n"); // Sort members into varieties ast_list_t pub_fields = { NULL, NULL, NULL }; ast_list_t news = { NULL, NULL, NULL }; ast_list_t bes = { NULL, NULL, NULL }; ast_list_t funs = { NULL, NULL, NULL }; for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { switch(ast_id(p)) { case TK_FVAR: case TK_FLET: doc_list_add_named(&pub_fields, p, 0, true, false); break; case TK_NEW: doc_list_add_named(&news, p, 1, true, true); break; case TK_BE: doc_list_add_named(&bes, p, 1, true, true); break; case TK_FUN: doc_list_add_named(&funs, p, 1, true, true); break; default: assert(0); break; } } // Handle member variety lists doc_fields(docgen, &pub_fields, "Public fields"); doc_methods(docgen, &news, "Constructors"); doc_methods(docgen, &bes, "Behaviours"); doc_methods(docgen, &funs, "Functions"); doc_list_free(&pub_fields); doc_list_free(&news); doc_list_free(&bes); doc_list_free(&funs); fclose(docgen->type_file); docgen->type_file = NULL; }
// Write a description of the given entity to its own type file. static void doc_entity(docgen_t* docgen, ast_t* ast) { assert(docgen != NULL); assert(docgen->index_file != NULL); assert(docgen->package_file != NULL); assert(docgen->test_types != NULL); assert(docgen->public_types != NULL); assert(docgen->private_types != NULL); assert(docgen->type_file == NULL); assert(ast != NULL); // First open a file size_t tqfn_len; char* tqfn = write_tqfn(ast, NULL, &tqfn_len); docgen->type_file = doc_open_file(docgen, true, tqfn, ".md"); if(docgen->type_file == NULL) return; // Add reference to new file to index file AST_GET_CHILDREN(ast, id, tparams, cap, provides, members, c_api, doc); const char* name = ast_name(id); assert(name != NULL); fprintf(docgen->index_file, " - %s %s: \"%s.md\"\n", ast_get_print(ast), name, tqfn); // Add to appropriate package types buffer printbuf_t* buffer = docgen->public_types; if(is_for_testing(name, provides)) buffer = docgen->test_types; else if(name[0] == '_') buffer = docgen->private_types; printbuf(buffer, "* [%s %s](%s.md)\n", ast_get_print(ast), name, tqfn); ponyint_pool_free_size(tqfn_len, tqfn); // Now we can write the actual documentation for the entity fprintf(docgen->type_file, "# %s", name); doc_type_params(docgen, tparams, true); fprintf(docgen->type_file, "\n\n"); if(ast_id(doc) != TK_NONE) fprintf(docgen->type_file, "%s\n\n", ast_name(doc)); // code block fprintf(docgen->type_file, "```pony\n"); fprintf(docgen->type_file, "%s ",ast_get_print(ast)); const char* cap_text = doc_get_cap(cap); if(cap_text != NULL) fprintf(docgen->type_file, "%s ", cap_text); fprintf(docgen->type_file, "%s", name); doc_type_params(docgen, tparams, false); doc_type_list(docgen, provides, " is\n ", ",\n ", "", false); fprintf(docgen->type_file, "\n```\n\n"); if (ast_id(ast) != TK_TYPE) doc_type_list(docgen, provides, "#### Implements\n\n* ", "\n* ", "\n\n---\n\n", true); else doc_type_list(docgen, provides, "#### Type Alias For\n\n* ", "\n* ", "\n\n---\n\n", true); // Sort members into varieties ast_list_t pub_fields = { NULL, NULL, NULL }; ast_list_t news = { NULL, NULL, NULL }; ast_list_t pub_bes = { NULL, NULL, NULL }; ast_list_t priv_bes = { NULL, NULL, NULL }; ast_list_t pub_funs = { NULL, NULL, NULL }; ast_list_t priv_funs = { NULL, NULL, NULL }; for(ast_t* p = ast_child(members); p != NULL; p = ast_sibling(p)) { switch(ast_id(p)) { case TK_FVAR: case TK_FLET: case TK_EMBED: doc_list_add_named(&pub_fields, p, 0, true, false); break; case TK_NEW: doc_list_add_named(&news, p, 1, true, true); break; case TK_BE: doc_list_add_named(&pub_bes, p, 1, true, false); doc_list_add_named(&priv_bes, p, 1, false, true); break; case TK_FUN: doc_list_add_named(&pub_funs, p, 1, true, false); doc_list_add_named(&priv_funs, p, 1, false, true); break; default: assert(0); break; } } // Handle member variety lists doc_methods(docgen, &news, "Constructors"); doc_fields(docgen, &pub_fields, "Public fields"); doc_methods(docgen, &pub_bes, "Public Behaviours"); doc_methods(docgen, &pub_funs, "Public Functions"); doc_methods(docgen, &priv_bes, "Private Behaviours"); doc_methods(docgen, &priv_funs, "Private Functions"); doc_list_free(&pub_fields); doc_list_free(&news); doc_list_free(&pub_bes); doc_list_free(&priv_bes); doc_list_free(&pub_funs); doc_list_free(&priv_funs); fclose(docgen->type_file); docgen->type_file = NULL; }