flecks/packages/dox/build/parser.js

136 lines
3.6 KiB
JavaScript
Raw Normal View History

2024-01-16 00:28:20 -06:00
const {readFile} = require('fs/promises');
2024-01-26 06:42:43 -06:00
const {dirname, join, relative} = require('path');
2022-03-07 00:21:16 -06:00
2024-01-16 00:28:20 -06:00
const {transformAsync} = require('@babel/core');
2024-01-20 04:31:37 -06:00
const {default: traverse} = require('@babel/traverse');
2024-01-16 00:28:20 -06:00
const {glob} = require('@flecks/core/server');
2022-03-07 00:21:16 -06:00
2024-01-23 09:06:00 -06:00
const {
buildFileVisitor,
configVisitor,
hookImplementationVisitor,
hookInvocationVisitor,
hookSpecificationVisitor,
todoVisitor,
} = require('./visitors');
2022-03-07 00:21:16 -06:00
2024-01-23 09:06:00 -06:00
exports.parseCode = async (code) => {
const {ast} = await transformAsync(code, {ast: true, code: false});
return ast;
};
2022-03-09 08:51:10 -06:00
2024-01-23 09:06:00 -06:00
exports.parseNormalSource = async (path, source) => {
const ast = await exports.parseCode(source);
const buildFiles = [];
const configs = [];
const hookImplementations = [];
const hookInvocations = [];
const todos = [];
const pushOne = (array) => (element) => {
array.push(element);
};
traverse(ast, buildFileVisitor(pushOne(buildFiles)));
traverse(ast, configVisitor((config) => {
const {description, key, location: {start: {index: start}, end: {index: end}}} = config;
configs.push({
defaultValue: source.slice(start, end),
description,
key,
2022-03-09 14:43:54 -06:00
});
2024-01-23 09:06:00 -06:00
}));
traverse(ast, hookImplementationVisitor((hookImplementation) => {
const {key: {value: hook}, loc: {start: {column, line}}} = hookImplementation;
hookImplementations.push({
column,
hook,
line,
});
}));
traverse(ast, hookInvocationVisitor((hookInvocation) => {
const isClassFile = [
'@flecks/core/build/flecks.js',
'@flecks/build/build/build.js',
]
.includes(path);
if (!isClassFile && hookInvocation.isThis) {
return;
2022-03-07 00:21:16 -06:00
}
2024-01-23 09:06:00 -06:00
const {location: {start: {column, line}}, hook, type} = hookInvocation;
hookInvocations.push({
column,
hook,
line,
type,
});
}));
traverse(ast, todoVisitor((todo) => {
const {description, location: {start: {index: start}, end: {index: end}}} = todo;
todos.push({
context: source.slice(start, end),
description,
});
}));
return {
buildFiles,
config: configs,
hookImplementations,
hookInvocations,
todos,
2022-03-07 00:21:16 -06:00
};
};
2024-01-23 09:06:00 -06:00
exports.parseHookSpecificationSource = async (path, source) => {
2024-01-16 00:28:20 -06:00
const ast = await exports.parseCode(source);
2024-01-23 09:06:00 -06:00
const hookSpecifications = [];
traverse(ast, hookSpecificationVisitor((hookSpecification) => {
const {
description,
hook,
location: {start: {index: start}, end: {index: end}},
params,
} = hookSpecification;
hookSpecifications.push({
description,
example: source.slice(start, end),
hook,
params,
});
}));
return {
hookSpecifications,
};
2022-03-07 00:21:16 -06:00
};
2024-01-23 09:06:00 -06:00
exports.parseSource = async (path, source) => {
if (path.match(/build\/flecks\.hooks\.js$/)) {
return exports.parseHookSpecificationSource(path, source);
2022-03-07 00:21:16 -06:00
}
2024-01-23 09:06:00 -06:00
return exports.parseNormalSource(path, source);
2022-03-07 00:21:16 -06:00
};
2024-01-25 06:42:31 -06:00
exports.parseFleckRoot = async (request) => (
2024-01-23 09:06:00 -06:00
Promise.all(
(await Promise.all([
2024-01-25 06:42:31 -06:00
...await glob(join(request, 'src', '**', '*.js')),
...await glob(join(request, 'build', '**', '*.js')),
2024-01-23 09:06:00 -06:00
]))
2024-01-25 06:42:31 -06:00
.map((filename) => [relative(request, filename), filename])
2024-01-23 09:06:00 -06:00
.map(async ([path, filename]) => {
const buffer = await readFile(filename);
return [path, await exports.parseSource(path, buffer.toString('utf8'))];
2022-03-07 00:21:16 -06:00
}),
2024-01-23 09:06:00 -06:00
)
);
exports.parseFlecks = async (flecks) => (
Promise.all(
2024-01-25 06:42:31 -06:00
flecks.roots
2024-01-26 06:42:43 -06:00
.map(async ([path, request]) => [
path,
await exports.parseFleckRoot(
dirname(await flecks.resolver.resolve(join(request, 'package.json'))),
),
]),
2024-01-23 09:06:00 -06:00
)
);