This code provides a function to statically replace dynamic imports in code by analyzing the Abstract Syntax Tree (AST) and substituting them with predefined templates. It leverages a custom importer
module and transpile
function to achieve this transformation.
npm run import -- "replace notebook import"
var importer = require('../Core')
var {selectAst} = importer.import("select code tree")
var {transpile} = importer.import("transpile code")
var niceName = importer.import("rename cell to nice name")
var {htmlToTree} = importer.import("html to tree")
var IMPORT_CALLS = `//CallExpression[
./*/Identifier[@name="import" or @name="importNotebook"]]`
function getImportTemplate(imports) {
throw new Error('TODO: multiple import template')
}
function replaceImport("ctx") {
var str = selectAst([`./Literal/@value`], ctx)[0]
if(!str) {
throw new Error(`Error: dynamic include ${ctx.ownerDocument.toString(ctx)}, TODO: include Core`)
}
var result = importer.interpret(str)
if(Array.isArray(result)) {
template = getImportTemplate(imports)
} else {
template = selectAst([`//CallExpression`], `require("./${niceName(result)}")`)[0]
}
var parent = ctx.parentNode
parent.replaceChild(template, ctx)
template.setAttribute('parent-attr', 'init')
}
function replaceImports(code) {
return transpile([
[IMPORT_CALLS, replaceImport]
], code)
}
module.exports = {
replaceImports
}
// Import dependencies
const { selectAst, transpile, htmlToTree, renameCellToNiceName } = require('../Core');
// Regular expression for import calls
const IMPORT_CALLS = /\/\/CallExpression\[\.\*\/Identifier\[(@name="import" or @name="importNotebook")\]\]/;
/**
* Generates an import template from an array of imports.
*
* @param {Array} imports - The array of imports.
* @returns {string} The import template.
*/
function getImportTemplate(imports) {
// If there's only one import, return a single import template.
if (imports.length === 1) {
return `require("./${renameCellToNiceName(imports[0])}")`;
}
// If there are multiple imports, throw an error as this function is not implemented.
throw new Error('TODO: multiple import template');
}
/**
* Replaces an import call with a template.
*
* @param {Object} ctx - The context of the import call.
*/
function replaceImport(ctx) {
// Select the value of the import call.
const str = selectAst(['./Literal/@value'], ctx)[0];
// If the value is empty, throw an error.
if (!str) {
throw new Error(`Error: dynamic include ${ctx.ownerDocument.toString(ctx)}`);
}
// Interpret the import call.
const result = selectHtml('require("./${niceName(${str})}")');
if (Array.isArray(result)) {
// If the result is an array, generate a template from it.
const imports = result.map(item => selectAttribute(item, 'value'));
const template = getImportTemplate(imports);
} else {
// If the result is not an array, select the call expression and rename it to a nice name.
const parent = ctx.parentNode;
const template = selectAst(['//CallExpression'], result)[0];
template.setAttribute('parent-attr', 'init');
parent.replaceChild(template, ctx);
}
}
/**
* Replaces all import calls in the given code.
*
* @param {string} code - The code to replace import calls in.
* @returns {string} The code with import calls replaced.
*/
function replaceImports(code) {
return transpile([
[IMPORT_CALLS, replaceImport]
], code);
}
module.exports = {
replaceImports
};
// Helper function to select a value from an HTML element.
function selectValue(element) {
return element.querySelector('value');
}
// Helper function to select a value from an HTML element.
function selectAttribute(element, name) {
return element.getAttribute(name);
}
// Helper function to select an HTML element.
function selectHtml(str) {
return htmlToTree(str);
}
This code defines a function to replace dynamic imports in code with static imports based on a template.
Here's a breakdown:
Imports:
importer
: A custom module for importing other modules.selectAst
: A function for selecting nodes in an Abstract Syntax Tree (AST).transpile
: A function for transpiling code.niceName
: A function for renaming a cell to a more suitable name.htmlToTree
: A function for converting HTML to an AST.IMPORT_CALLS
Constant:
getImportTemplate
Function:
replaceImport
Function:
replaceImports
Function:
transpile
to apply the replaceImport
function to all nodes matching the IMPORT_CALLS
query.Module Exports:
replaceImports
function.