js-slang
Version:
Javascript-based implementations of Source, written in Typescript
110 lines • 4.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.speciferToString = exports.getImportedName = void 0;
exports.getModuleDeclarationSource = getModuleDeclarationSource;
exports.extractIdsFromPattern = extractIdsFromPattern;
exports.getIdsFromDeclaration = getIdsFromDeclaration;
exports.getSourceVariableDeclaration = getSourceVariableDeclaration;
exports.hasNoDeclarations = hasNoDeclarations;
exports.hasNoImportDeclarations = hasNoImportDeclarations;
exports.filterImportDeclarations = filterImportDeclarations;
const assert_1 = require("../assert");
const dict_1 = require("../dict");
const typeGuards_1 = require("./typeGuards");
const walkers_1 = require("./walkers");
function getModuleDeclarationSource(node) {
(0, assert_1.default)(typeof node.source?.value === 'string', `Expected ${node.type} to have a source value of type string, got ${node.source?.value}`);
return node.source.value;
}
function extractIdsFromPattern(pattern) {
const identifiers = [];
(0, walkers_1.simple)(pattern, {
Identifier: (node) => {
identifiers.push(node);
}
});
return identifiers;
}
function getIdsFromDeclaration(decl, allowNull) {
const rawIds = (0, typeGuards_1.isVariableDeclaration)(decl)
? decl.declarations.flatMap(({ id }) => extractIdsFromPattern(id))
: [decl.id];
if (!allowNull) {
rawIds.forEach(each => {
(0, assert_1.default)(each !== null, 'Encountered a null identifier!');
});
}
return rawIds;
}
/**
* Since Variable declarations in Source programs must be initialized and are guaranteed to only
* have 1 declarator, this function unwraps variable declarations and its single declarator
* into its id and init
*/
function getSourceVariableDeclaration(decl) {
(0, assert_1.default)(decl.declarations.length === 1, 'Variable Declarations in Source should only have 1 declarator!');
const [declaration] = decl.declarations;
(0, assert_1.default)((0, typeGuards_1.isIdentifier)(declaration.id), 'Variable Declarations in Source should be declared using an Identifier!');
(0, assert_1.default)(!!declaration.init, 'Variable declarations in Source must be initialized!');
return {
id: declaration.id,
init: declaration.init,
loc: declaration.loc
};
}
const getImportedName = (spec) => {
switch (spec.type) {
case 'ImportDefaultSpecifier':
return 'default';
case 'ImportSpecifier':
return spec.imported.name;
case 'ExportSpecifier':
return spec.local.name;
}
};
exports.getImportedName = getImportedName;
const speciferToString = (spec) => {
switch (spec.type) {
case 'ImportSpecifier': {
if (spec.imported.name === spec.local.name) {
return spec.imported.name;
}
return `${spec.imported.name} as ${spec.local.name}`;
}
case 'ImportDefaultSpecifier':
return `default as ${spec.local.name}`;
case 'ExportSpecifier': {
if (spec.local.name === spec.exported.name) {
return spec.local.name;
}
return `${spec.local.name} as ${spec.exported.name}`;
}
}
};
exports.speciferToString = speciferToString;
/**
* Returns true if the array of statements doesn't contain any declarations
*/
function hasNoDeclarations(stmt) {
return !stmt.some(typeGuards_1.isDeclaration);
}
/**
* Returns true if the array of statements doesn't contain any import declarations
*/
function hasNoImportDeclarations(stmt) {
return !stmt.some(typeGuards_1.isImportDeclaration);
}
/**
* Filters out all import declarations from a program, and sorts them by
* the module they import from
*/
function filterImportDeclarations({ body }) {
return body.reduce(([importNodes, otherNodes], node) => {
if (!(0, typeGuards_1.isImportDeclaration)(node))
return [importNodes, [...otherNodes, node]];
const moduleName = getModuleDeclarationSource(node);
importNodes.add(moduleName, node);
return [importNodes, otherNodes];
}, [new dict_1.ArrayMap(), []]);
}
//# sourceMappingURL=helpers.js.map