main.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. const fs = require("fs");
  2. const path_ = require("path");
  3. const rootdir = path_.resolve(process.argv[2] ?? '.');
  4. const parser = require('@babel/parser');
  5. const traverse = require('@babel/traverse').default;
  6. const { ModuleDoc } = require("./defs");
  7. const doc_module = new ModuleDoc();
  8. // List files in this directory
  9. const files = fs.readdirSync(rootdir);
  10. for ( const file of files ) {
  11. const stat = fs.statSync(path_.join(rootdir, file));
  12. if ( stat.isDirectory() ) {
  13. continue;
  14. }
  15. if ( ! file.endsWith('.js') ) continue;
  16. const type =
  17. file.endsWith('Service.js') ? 'service' :
  18. file.endsWith('Module.js') ? 'module' :
  19. null;
  20. if ( type === null ) continue;
  21. console.log('file', file);
  22. const code = fs.readFileSync(path_.join(rootdir, file), 'utf8');
  23. const ast = parser.parse(code);
  24. traverse(ast, {
  25. CallExpression (path) {
  26. const callee = path.get('callee');
  27. if ( ! callee.isIdentifier() ) return;
  28. if ( callee.node.name === 'require' ) {
  29. doc_module.requires.push(path.node.arguments[0].value);
  30. }
  31. },
  32. ClassDeclaration (path) {
  33. const node = path.node;
  34. const name = node.id.name;
  35. // Skip utility classes (for now)
  36. if ( name !== file.slice(0, -3) ) {
  37. return;
  38. }
  39. const comment = (node.leadingComments && (
  40. node.leadingComments.length < 1 ? '' :
  41. node.leadingComments[node.leadingComments.length - 1]
  42. )) ?? '';
  43. let doc_item = doc_module;
  44. if ( type !== 'module' ) {
  45. doc_item = doc_module.add_service();
  46. }
  47. doc_item.name = name;
  48. if ( comment !== '' ) {
  49. doc_item.provide_comment(comment);
  50. }
  51. if ( type === 'module' ) {
  52. return;
  53. }
  54. if ( comment !== '' ) {
  55. doc_item.provide_comment(comment);
  56. // to_service_add_comment(def_service, comment);
  57. }
  58. console.log('class', name);
  59. path.node.body.body.forEach(member => {
  60. const key = member.key.name ?? member.key.value;
  61. const comment = member.leadingComments?.[0]?.value ?? '';
  62. if ( key.startsWith('__on_') ) {
  63. // 2nd argument is always an object destructuring;
  64. // we want the list of keys in the object:
  65. const params = member.params?.[1]?.properties ?? [];
  66. doc_item.provide_listener({
  67. key: key.slice(5),
  68. comment,
  69. params,
  70. });
  71. }
  72. console.log(member.type, key, member.leadingComments);
  73. });
  74. }
  75. })
  76. }
  77. const outfile = path_.join(rootdir, 'README.md');
  78. const out = doc_module.toMarkdown();
  79. fs.writeFileSync(outfile, out);