notebook | Cell 6 | test add missing imports | Search

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.

Run example

npm run import -- "add missing imports"

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
}

What the code could have been:

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: