Пример #1
0
// Write the given package home page to its own file
static void doc_package_home(docgen_t* docgen,
  ast_t* package,
  ast_t* doc_string)
{
  assert(docgen != NULL);
  assert(docgen->index_file != NULL);
  assert(docgen->home_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(package != NULL);
  assert(ast_id(package) == TK_PACKAGE);

  // First open a file
  size_t tqfn_len;
  char* tqfn = write_tqfn(package, "-index", &tqfn_len);

  // Package group
  fprintf(docgen->index_file, "- package %s:\n",
    package_qualified_name(package));

  docgen->type_file = doc_open_file(docgen, true, tqfn, ".md");

  if(docgen->type_file == NULL)
    return;

  // Add reference to new file to index file
  fprintf(docgen->index_file, "  - Package: \"%s.md\"\n", tqfn);

  // Add reference to package to home file
  fprintf(docgen->home_file, "* [%s](%s)\n", package_qualified_name(package),
    tqfn);

  // Now we can write the actual documentation for the package
  if(doc_string != NULL)
  {
    assert(ast_id(doc_string) == TK_STRING);
    fprintf(docgen->type_file, "%s", ast_name(doc_string));
  }
  else
  {
    fprintf(docgen->type_file, "No package doc string provided for %s.",
      package_qualified_name(package));
  }


  ponyint_pool_free_size(tqfn_len, tqfn);

  docgen->test_types = printbuf_new();
  docgen->public_types = printbuf_new();
  docgen->private_types = printbuf_new();
  docgen->package_file = docgen->type_file;
  docgen->type_file = NULL;
}
Пример #2
0
// Document the packages in the given program
static void doc_packages(docgen_t* docgen, ast_t* ast)
{
  assert(ast != NULL);
  assert(ast_id(ast) == TK_PROGRAM);

  // The Main package appears first, other packages in alphabetical order
  ast_t* package_1 = NULL;

  ast_list_t packages = { NULL, NULL, NULL };

  // Sort packages
  for(ast_t* p = ast_child(ast); p != NULL; p = ast_sibling(p))
  {
    assert(ast_id(p) == TK_PACKAGE);

    if(strcmp(package_name(p), "$0") == 0)
    {
      assert(package_1 == NULL);
      package_1 = p;
    }
    else
    {
      const char* name = package_qualified_name(p);
      doc_list_add(&packages, p, name);
    }
  }

  // Process packages
  assert(package_1 != NULL);
  doc_package(docgen, package_1);

  for(ast_list_t* p = packages.next; p != NULL; p = p->next)
    doc_package(docgen, p->ast);
}
Пример #3
0
// Write the TQFN for the given type to a new buffer.
// By default the type name is taken from the given AST, however this can be
// overridden by the type_name parameter. Pass NULL to use the default.
// The returned buffer must be freed using pool_free_size when no longer
// needed. Note that the size reported is the size of the buffer and includes a
// terminator.
static char* write_tqfn(ast_t* type, const char* type_name, size_t* out_size)
{
  assert(type != NULL);
  assert(out_size != NULL);

  ast_t* package = ast_nearest(type, TK_PACKAGE);
  assert(package != NULL);

  // We need the qualified package name and the type name
  const char* pkg_qual_name = package_qualified_name(package);

  if(type_name == NULL)
    type_name = ast_name(ast_child(type));

  assert(pkg_qual_name != NULL);
  assert(type_name != NULL);

  char* buffer = doc_cat(pkg_qual_name, "-", type_name, "", "", out_size);

  // Change slashes to dashes
  for(char* p = buffer; *p != '\0'; p++)
  {
    if(*p == '/')
      *p = '-';
  }

  return buffer;
}
Пример #4
0
// Document the packages in the given program
static void doc_packages(docgen_t* docgen, ast_t* ast)
{
  assert(ast != NULL);
  assert(ast_id(ast) == TK_PROGRAM);

  // The Main package appears first, other packages in alphabetical order
  ast_t* package_1 = ast_child(ast);
  assert(package_1 != NULL);

  ast_list_t packages = { NULL, NULL, NULL };

  // Sort packages
  for(ast_t* p = ast_sibling(package_1); p != NULL; p = ast_sibling(p))
  {
    assert(ast_id(p) == TK_PACKAGE);

    const char* name = package_qualified_name(p);
    doc_list_add(&packages, p, name, true);
  }

  // Process packages
  docgen->package_file = NULL;
  docgen->test_types = NULL;
  docgen->public_types = NULL;
  docgen->private_types = NULL;
  doc_package(docgen, package_1);

  for(ast_list_t* p = packages.next; p != NULL; p = p->next)
    doc_package(docgen, p->ast);
}
Пример #5
0
// 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;
}