This code provides a function, addImports
, that automatically inserts import statements into code based on the identification of global function calls. It leverages an AST parser, a cache of exports, and a transpiling function to achieve this.
npm run import -- "add missing imports"
var importer = require('../Core')
var {transpile} = importer.import("transpile code")
var {selectAst} = importer.import("select code tree")
var niceName = importer.import("rename cell to nice name")
var exportsCache = importer.import("exports cache")
var GLOBAL_CALLS = `//CallExpression[
not(./parent::MemberExpression)
and not(//*[contains(@type, "Declar")]/Identifier/@name=./Identifier/@name)
]`
/*
[
and not(//MemberExpression/Identifier/@name=./Identifier/@name)
]
*/
var notebookExports;
function addImport("ctx") {
var id = selectAst(`./Identifier/@name`, ctx)
var file = exportsCache.filter(e => e[2].includes(id))
if(file.length === 1) {
var body = selectAst([`//Program`], ctx)[0]
var include = selectAst([`//Program/*`],
`var ${id} = importNotebook()`)[0]
body.insertBefore(include, body.childNodes[0] || null)
} else if (file.length > 1) {
throw new Error(`undefined ${id}, couldn't import ${JSON.stringify(file)}`)
}
}
function addImports(code) {
return transpile([
[GLOBAL_CALLS, addImport]
], code)
}
module.exports = {
addImports
}
const { transpile, selectAst } = require('../Core');
// Constants
const GLOBAL_CALLS = `
//CallExpression[
not(./parent::MemberExpression)
and not(//*[contains(@type, "Declar")]/Identifier/@name=./Identifier/@name)
]
`;
const EXPORTS_CACHE_KEY = 'exportsCache';
// Function to add import statements
async function addImport({
ast,
id,
exportsCache,
}) {
// Filter exports cache to find matching file
const file = exportsCache.filter((e) => e[2].includes(id));
if (file.length === 1) {
// Select program node from AST
const program = selectAst('//Program', ast)[0];
const include = selectAst('//Program/*', `var ${id} = importNotebook("${file[0]}")`, ast)[0];
// Insert import statement at the beginning of the program
program.insertBefore(include, program.childNodes[0] || null);
} else if (file.length > 1) {
throw new Error(`undefined ${id}, couldn't import ${JSON.stringify(file)}`);
}
}
// Function to add import statements to the code
async function addImports(code) {
try {
// Transpile code with addImport function
return await transpile([{ test: GLOBAL_CALLS, run: addImport }], code);
} catch (error) {
// Handle any transpile errors
throw error;
}
}
// Export addImports function
module.exports = { addImports };
This code defines a function to automatically add imports to a code snippet based on global function calls.
Here's a breakdown:
Core
library, including functions for transpiling code, selecting parts of an Abstract Syntax Tree (AST), renaming code elements, and managing exports.GLOBAL_CALLS
to identify global function calls within the code.addImport
Function: This function takes an AST context and identifies the name of a global function call. It then searches for a matching export in a cache (exportsCache
) and inserts an import statement into the code if found.addImports
Function: This function takes a code snippet as input, transpiles it using the imported transpile
function, and applies the addImport
function to the AST to add the necessary imports.addImports
function, making it available for use in other parts of the project.