Skip to content

Commit 953f248

Browse files
committed
partial review addressed
Signed-off-by: flakey5 <[email protected]>
1 parent 2939177 commit 953f248

File tree

10 files changed

+107
-49
lines changed

10 files changed

+107
-49
lines changed

bin/cli.mjs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { coerce } from 'semver';
99
import { DOC_NODE_CHANGELOG_URL, DOC_NODE_VERSION } from '../src/constants.mjs';
1010
import createGenerator from '../src/generators.mjs';
1111
import generators from '../src/generators/index.mjs';
12-
import createLoader from '../src/loader.mjs';
13-
import createParser from '../src/parser.mjs';
12+
import { createMarkdownLoader } from '../src/loader.mjs';
13+
import { createMarkdownParser } from '../src/parser.mjs';
1414
import createNodeReleases from '../src/releases.mjs';
1515

1616
const availableGenerators = Object.keys(generators);
@@ -68,25 +68,23 @@ program
6868
*/
6969
const { input, output, target = [], version, changelog } = program.opts();
7070

71-
const { loadMarkdownFiles, loadJsFiles } = createLoader();
72-
const { parseApiDocs, parseJsSources } = createParser();
71+
const { loadFiles } = createMarkdownLoader();
72+
const { parseApiDocs } = createMarkdownParser();
7373

74-
const apiDocFiles = loadMarkdownFiles(input);
74+
const apiDocFiles = loadFiles(input);
7575

7676
const parsedApiDocs = await parseApiDocs(apiDocFiles);
7777

78-
const sourceFiles = loadJsFiles(input);
79-
80-
const parsedJsFiles = await parseJsSources(sourceFiles);
81-
82-
const { runGenerators } = createGenerator(parsedApiDocs, parsedJsFiles);
78+
const { runGenerators } = createGenerator(parsedApiDocs);
8379

8480
// Retrieves Node.js release metadata from a given Node.js version and CHANGELOG.md file
8581
const { getAllMajors } = createNodeReleases(changelog);
8682

8783
await runGenerators({
8884
// A list of target modes for the API docs parser
8985
generators: target,
86+
// Resolved `input` to be used
87+
input: input,
9088
// Resolved `output` path to be used
9189
output: resolve(output),
9290
// Resolved SemVer of current Node.js version

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/generators/api-links/index.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export default {
3030
description:
3131
'Creates a mapping of publicly accessible functions to their source locations in the Node.js repository.',
3232

33+
// Unlike the rest of the generators, this utilizes Javascript sources being
34+
// passed into the input field rather than Markdown.
3335
dependsOn: 'ast-js',
3436

3537
/**

src/generators/api-links/utils/getBaseGitHubUrl.mjs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ export function getBaseGitHubUrl(cwd) {
1313
// Ex/ git@github.com:nodejs/node.git -> https://github.com/nodejs/node.git
1414
let [, repository] = url.split(':');
1515

16-
// Trim off the trailing .git if it exists
17-
if (repository.endsWith('.git')) {
18-
repository = repository.substring(0, repository.length - 4);
19-
}
20-
2116
url = `https://github.com/${repository}`;
2217
}
2318

19+
// https://github.com/nodejs/node.git -> https://github.com/nodejs/node
20+
if (url.endsWith('.git')) {
21+
url = url.substring(0, url.length - 4);
22+
}
23+
2424
return url;
2525
}
2626

src/generators/ast-js/index.mjs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { createJsLoader } from '../../loader.mjs';
2+
import { createJsParser } from '../../parser.mjs';
3+
4+
/**
5+
* This generator parses Javascript sources passed into the generator's input
6+
* field. This is separate from the Markdown parsing step since it's not as
7+
* commonly used and can take up a significant amount of memory.
8+
*
9+
* Putting this with the rest of the generators allows it to be lazily loaded
10+
* so we're only parsing the Javascript sources when we need to.
11+
*
12+
* @typedef {unknown} Input
13+
*
14+
* @type {import('../types.d.ts').GeneratorMetadata<Input, Array<JsProgram>>}
15+
*/
16+
export default {
17+
name: 'ast-js',
18+
19+
version: '1.0.0',
20+
21+
description: 'Parses Javascript source files passed into the input.',
22+
23+
dependsOn: 'ast',
24+
25+
/**
26+
* @param {Input} _
27+
* @param {Partial<GeneratorOptions>} options
28+
*/
29+
async generate(_, options) {
30+
const { loadFiles } = createJsLoader();
31+
32+
if (!options.input) {
33+
return [];
34+
}
35+
36+
// Load all of the Javascript sources into memory
37+
const sourceFiles = loadFiles(options.input);
38+
39+
const { parseJsSources } = createJsParser();
40+
41+
// Parse the Javascript sources into ASTs
42+
const parsedJsFiles = await parseJsSources(sourceFiles);
43+
44+
// Return the ASTs so they can be used in another generator
45+
return parsedJsFiles;
46+
},
47+
};

src/generators/index.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import legacyJson from './legacy-json/index.mjs';
88
import legacyJsonAll from './legacy-json-all/index.mjs';
99
import addonVerify from './addon-verify/index.mjs';
1010
import apiLinks from './api-links/index.mjs';
11+
import astJs from './ast-js/index.mjs';
1112

1213
export default {
1314
'json-simple': jsonSimple,
@@ -18,4 +19,5 @@ export default {
1819
'legacy-json-all': legacyJsonAll,
1920
'addon-verify': addonVerify,
2021
'api-links': apiLinks,
22+
'ast-js': astJs,
2123
};

src/generators/types.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ declare global {
99

1010
// This is the runtime config passed to the API doc generators
1111
export interface GeneratorOptions {
12+
// The path to the input source files. This parameter accepts globs and can
13+
// be a glob when passed to a generator.
14+
input: string | string[];
15+
1216
// The path used to output generated files, this is to be considered
1317
// the base path that any generator will use for generating files
1418
// This parameter accepts globs but when passed to generators will contain

src/index.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
export * as constants from './constants.mjs';
22
export { default as generators } from './generators/index.mjs';
33
export { default as createGenerator } from './generators.mjs';
4-
export { default as createLoader } from './loader.mjs';
4+
export * from './loader.mjs';
55
export { default as createMetadata } from './metadata.mjs';
6-
export { default as createParser } from './parser.mjs';
6+
export * from './parser.mjs';
77
export { default as createQueries } from './queries.mjs';
88
export { default as createNodeReleases } from './releases.mjs';

src/loader.mjs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { VFile } from 'vfile';
1111
* could be used for different things, but here we want to use it to load
1212
* Markdown files and transform them into VFiles
1313
*/
14-
const createLoader = () => {
14+
export const createMarkdownLoader = () => {
1515
/**
1616
* Loads API Doc files and transforms it into VFiles
1717
*
@@ -21,7 +21,7 @@ const createLoader = () => {
2121
*
2222
* @see https://code.visualstudio.com/docs/editor/glob-patterns
2323
*/
24-
const loadMarkdownFiles = searchPath => {
24+
const loadFiles = searchPath => {
2525
const resolvedFiles = globSync(searchPath).filter(
2626
filePath => extname(filePath) === '.md'
2727
);
@@ -33,12 +33,19 @@ const createLoader = () => {
3333
});
3434
};
3535

36+
return { loadFiles };
37+
};
38+
39+
/**
40+
* This creates a "loader" for loading Javascript source files into VFiles.
41+
*/
42+
export const createJsLoader = () => {
3643
/**
3744
* Loads the JavaScript source files and transforms them into VFiles
3845
*
39-
* @param {Array<string>} searchPath
46+
* @param {string | Array<string>} searchPath
4047
*/
41-
const loadJsFiles = searchPath => {
48+
const loadFiles = searchPath => {
4249
const resolvedFiles = globSync(searchPath).filter(
4350
filePath => extname(filePath) === '.js'
4451
);
@@ -50,7 +57,5 @@ const createLoader = () => {
5057
});
5158
};
5259

53-
return { loadMarkdownFiles, loadJsFiles };
60+
return { loadFiles };
5461
};
55-
56-
export default createLoader;

src/parser.mjs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { createNodeSlugger } from './utils/slugger.mjs';
1616
/**
1717
* Creates an API doc parser for a given Markdown API doc file
1818
*/
19-
const createParser = () => {
19+
export const createMarkdownParser = () => {
2020
// Creates an instance of the Remark processor with GFM support
2121
// which is used for stringifying the AST tree back to Markdown
2222
const remarkProcessor = getRemark();
@@ -183,38 +183,40 @@ const createParser = () => {
183183
return resolvedApiDocEntries.flat();
184184
};
185185

186+
return { parseApiDocs, parseApiDoc };
187+
};
188+
189+
/**
190+
* Creates a Javascript source parser for a given source file
191+
*/
192+
export const createJsParser = () => {
186193
/**
187194
* Parses a given JavaScript file into an ESTree AST representation of it
188195
*
189-
* @param {import('vfile').VFile | Promise<import('vfile').VFile>} apiDoc
196+
* @param {import('vfile').VFile | Promise<import('vfile').VFile>} sourceFile
190197
* @returns {Promise<JsProgram>}
191198
*/
192-
const parseJsSource = async apiDoc => {
199+
const parseJsSource = async sourceFile => {
193200
// We allow the API doc VFile to be a Promise of a VFile also,
194201
// hence we want to ensure that it first resolves before we pass it to the parser
195-
const resolvedApiDoc = await Promise.resolve(apiDoc);
202+
const resolvedSourceFile = await Promise.resolve(sourceFile);
196203

197-
if (typeof resolvedApiDoc.value !== 'string') {
204+
if (typeof resolvedSourceFile.value !== 'string') {
198205
throw new TypeError(
199-
`expected resolvedApiDoc.value to be string but got ${typeof resolvedApiDoc.value}`
206+
`expected resolvedSourceFile.value to be string but got ${typeof resolvedSourceFile.value}`
200207
);
201208
}
202209

203-
try {
204-
const res = acorn.parse(resolvedApiDoc.value, {
205-
allowReturnOutsideFunction: true,
206-
ecmaVersion: 'latest',
207-
locations: true,
208-
});
209-
210-
return {
211-
...res,
212-
path: resolvedApiDoc.path,
213-
};
214-
} catch (err) {
215-
console.log(`error parsing ${resolvedApiDoc.basename}`);
216-
throw err;
217-
}
210+
const res = acorn.parse(resolvedSourceFile.value, {
211+
allowReturnOutsideFunction: true,
212+
ecmaVersion: 'latest',
213+
locations: true,
214+
});
215+
216+
return {
217+
...res,
218+
path: resolvedSourceFile.path,
219+
};
218220
};
219221

220222
/**
@@ -231,7 +233,5 @@ const createParser = () => {
231233
return resolvedApiDocEntries;
232234
};
233235

234-
return { parseApiDocs, parseApiDoc, parseJsSources, parseJsSource };
236+
return { parseJsSource, parseJsSources };
235237
};
236-
237-
export default createParser;

0 commit comments

Comments
 (0)