The getImports
function extracts import information from a given code string by parsing an Abstract Syntax Tree (AST) and selecting specific nodes using XPath-like query strings. It is exported as a module and returns an array of import information, removing duplicates in the process.
npm run import -- "get imports from source"
var importer = require('../Core');
var {selectAst} = importer.import("select code tree")
var CORE_DECLARE = `//*[
contains(@type, "Declar")
and ./*/*[@type="Literal" and contains(@value, "Core")]
]`;
var IMPORTER = `${CORE_DECLARE}/*[@type="Identifier"]/@name`;
var IMPORTER_CALLS = `//*[contains(@type, "Call") and ./*[
contains(@type, "Member") and contains(./Identifier/@name, "import")
] and ./Literal]`;
function getImports(code) {
var importer = selectAst([IMPORTER], code)[0]
return [].concat.apply([], selectAst([
IMPORTER_CALLS.replace('importer', importer),
[`./Identifier/@name|./*/Identifier/@name|.//Literal/@value`]
], code))
.filter((i, j, arr) => arr.indexOf(i) === j)
}
module.exports = getImports;
const { selectAst } = require('../Core');
// Define the selector for Core declarations
const CORE_DECLARE_SELECTOR = `
//[
@type="Declar"
and contains(@type, "Literal") and contains(@value, "Core")
]
`;
// Extract the importer name from the Core declaration
const IMPORTER_SELECTOR = (coreDeclaration) => `${coreDeclaration}/*[@type="Identifier"]/@name`;
// Define the selector for importer calls
const IMPORTER_CALLS_SELECTOR = `
//[
@type="Call"
and./*[
@type="Member"
and contains(./Identifier/@name, "import")
]
and./Literal
]
`;
/**
* Extracts imports from the given code.
*
* @param {string} code - The code to extract imports from.
* @returns {Array} An array of imports.
*/
function getImports(code) {
// Select the Core declaration
const coreDeclaration = selectAst([CORE_DECLARE_SELECTOR], code)[0];
// Extract the importer name
const importerName = IMPORTER_SELECTOR(coreDeclaration);
// Select importer calls
const importerCalls = selectAst([IMPORTER_CALLS_SELECTOR.replace('importer', importerName)], code);
// Extract the import names and values
const importNamesAndValues = importerCalls.map((importerCall) => {
const identifier = importerCall.querySelector('.//Identifier');
const literal = importerCall.querySelector('.//Literal');
return [
identifier? identifier.getAttribute('name') : null,
identifier? identifier.querySelector('./../*[@type="Identifier"]/@name') : null,
literal? literal.getAttribute('value') : null,
];
});
// Remove duplicates
const uniqueImports = [...new Set(importNamesAndValues.flat())];
return uniqueImports;
}
module.exports = getImports;
Code Breakdown
importer
: an object imported from ../Core
with a method selectAst
used to parse Abstract Syntax Trees (ASTs)selectAst
: function that selects nodes from an AST based on a query stringCORE_DECLARE
, IMPORTER
, IMPORTER_CALLS
: XPath-like query strings used to select specific nodes from the ASTgetImports
: a function that extracts import information from a given code stringselectAst
to find the first node matching the IMPORTER
query in the given code, and assigns it to importer
.selectAst
to find all nodes matching the IMPORTER_CALLS
query, replacing importer
with the actual node name.filter
method.The getImports
function is exported as a module.