doc: pick up chunked hooks

This commit is contained in:
cha0s 2024-02-14 07:48:16 -06:00
parent bc60b11847
commit 42e4e3413b
3 changed files with 81 additions and 7 deletions

View File

@ -304,10 +304,10 @@ exports.generateJson = async function generate(flecks) {
}
r.config[fleck] = config;
}
hookImplementations.forEach(({column, hook, line}) => {
hookImplementations.forEach(({column, filename, hook, line}) => {
ensureHook(hook);
r.hooks[hook].implementations.push({
filename: [join(root, path), line, column].join(':'),
filename: filename || [join(root, path), line, column].join(':'),
});
});
hookInvocations.forEach(({

View File

@ -1,5 +1,11 @@
const {readFile} = require('fs/promises');
const {dirname, join, relative} = require('path');
const {
basename,
dirname,
extname,
join,
relative,
} = require('path');
const {transformAsync} = require('@babel/core');
const {default: traverse} = require('@babel/traverse');
@ -8,6 +14,7 @@ const {glob} = require('@flecks/core/src/server');
const {
buildFileVisitor,
configVisitor,
hookBaseVisitor,
hookImplementationVisitor,
hookInvocationVisitor,
hookSpecificationVisitor,
@ -19,10 +26,11 @@ exports.parseCode = async (code, options = {}) => {
return ast;
};
exports.parseNormalSource = async (path, source, root, options) => {
exports.parseNormalSource = async (path, source, root, request, options) => {
const ast = await exports.parseCode(source, options);
const buildFiles = [];
const configs = [];
const hookBases = [];
const hookImplementations = [];
const hookInvocations = [];
const todos = [];
@ -38,6 +46,24 @@ exports.parseNormalSource = async (path, source, root, options) => {
key,
});
}));
traverse(ast, hookBaseVisitor((args) => {
const subpath = join(dirname(path), args[0].value);
const prefix = join(request, subpath);
const implementationSources = glob.sync(
join(prefix, '**'),
{nodir: true},
);
implementationSources.forEach((implementationSource) => {
const filename = relative(prefix, implementationSource);
const hook = join(dirname(filename), basename(filename, extname(filename)));
hookImplementations.push({
column: 1,
filename: join(root, subpath, filename),
hook,
line: 1,
});
});
}));
traverse(ast, hookImplementationVisitor((hookImplementation) => {
const {key: {value: hook}, loc: {start: {column, line}}} = hookImplementation;
hookImplementations.push({
@ -73,6 +99,7 @@ exports.parseNormalSource = async (path, source, root, options) => {
return {
buildFiles,
config: configs,
hookBases,
hookImplementations,
hookInvocations,
todos,
@ -94,11 +121,11 @@ exports.parseHookSpecificationSource = async (path, source, options) => {
};
};
exports.parseSource = async (path, source, root, options) => {
exports.parseSource = async (path, source, root, request, options) => {
if (path.match(/build\/flecks\.hooks\.js$/)) {
return exports.parseHookSpecificationSource(path, source, options);
}
return exports.parseNormalSource(path, source, root, options);
return exports.parseNormalSource(path, source, root, request, options);
};
exports.parseFleckRoot = async (root, request, options) => (
@ -110,7 +137,7 @@ exports.parseFleckRoot = async (root, request, options) => (
.map((filename) => [relative(request, filename), filename])
.map(async ([path, filename]) => {
const buffer = await readFile(filename);
return [path, await exports.parseSource(path, buffer.toString('utf8'), root, options)];
return [path, await exports.parseSource(path, buffer.toString('utf8'), root, request, options)];
}),
)
);

View File

@ -11,6 +11,7 @@ const {
isBlockStatement,
isReturnStatement,
isFunction,
isCallExpression,
} = require('@babel/types');
const {parse: parseComment} = require('comment-parser');
@ -23,6 +24,52 @@ function visitProperties(properties, fn) {
});
}
exports.hookBaseVisitor = (fn) => ({
// exports.hooks = Flecks.hooks(require.context(...))
AssignmentExpression(path) {
const {left, right} = path.node;
if (isMemberExpression(left)) {
if (isIdentifier(left.object) && 'exports' === left.object.name) {
if (isIdentifier(left.property) && 'hooks' === left.property.name) {
if (isCallExpression(right)) {
if (isMemberExpression(right.callee)) {
if (
isIdentifier(right.callee.object) && 'Flecks' === right.callee.object.name
&& isIdentifier(right.callee.property) && 'hooks' === right.callee.property.name
) {
if (isCallExpression(right.arguments[0])) {
if (
isIdentifier(right.arguments[0].callee.object)
&& 'require' === right.arguments[0].callee.object.name
&& isIdentifier(right.arguments[0].callee.property)
&& 'context' === right.arguments[0].callee.property.name
) {
fn(right.arguments[0].arguments);
}
}
}
}
}
}
}
}
},
// export const hooks = Flecks.hooks(...)
ExportNamedDeclaration(path) {
const {declaration} = path.node;
if (isVariableDeclaration(declaration)) {
const {declarations} = declaration;
declarations.forEach((declarator) => {
if ('hooks' === declarator.id.name) {
if (isObjectExpression(declarator.init)) {
visitProperties(declarator.init.properties, fn);
}
}
});
}
},
});
exports.hookImplementationVisitor = (fn) => ({
// exports.hooks = {...}
AssignmentExpression(path) {