js-slang
Version:
Javascript-based implementations of Source, written in Typescript
73 lines • 3.38 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("../../types");
const loader_1 = require("../loader");
const analyzer_1 = require("./analyzer");
const linker_1 = require("./linker");
const bundler_1 = require("./bundler");
/**
* Preprocesses file imports and returns a transformed Abstract Syntax Tree (AST).
* If an error is encountered at any point, returns `undefined` to signify that an
* error occurred. Details of the error can be found inside `context.errors`.
*
* The preprocessing works by transforming each imported file into a function whose
* parameters are other files (results of transformed functions) and return value
* is a pair where the head is the default export or null, and the tail is a list
* of pairs that map from exported names to identifiers.
*
* See https://github.com/source-academy/js-slang/wiki/Local-Module-Import-&-Export
* for more information.
*
* @param files An object mapping absolute file paths to file content.
* @param entrypointFilePath The absolute path of the entrypoint file.
* @param context The information associated with the program evaluation.
*/
const preprocessFileImports = async (files, entrypointFilePath, context, options = {}, bundler = bundler_1.default) => {
if (context.variant === types_1.Variant.TYPED) {
// Load typed source modules into context first to ensure that the type checker has access to all types.
// TODO: This is a temporary solution, and we should consider a better way to handle this.
try {
await (0, loader_1.loadSourceModuleTypes)(new Set(['rune', 'curve']), context);
}
catch (error) {
context.errors.push(error);
return {
ok: false,
verboseErrors: false
};
}
}
// Parse all files into ASTs and build the import graph.
const linkerResult = await (0, linker_1.default)(files, entrypointFilePath, context, options?.importOptions, !!options?.shouldAddFileName);
// Return 'undefined' if there are errors while parsing.
if (!linkerResult.ok) {
return linkerResult;
}
const { programs, topoOrder, sourceModulesToImport } = linkerResult;
try {
await (0, loader_1.default)(sourceModulesToImport, context, options.importOptions?.loadTabs ?? true);
// Run type checking on the programs after loading the source modules and their types.
const linkerResult = await (0, linker_1.default)(files, entrypointFilePath, context, options?.importOptions, !!options?.shouldAddFileName);
// Return 'undefined' if there are errors while parsing.
if (!linkerResult.ok) {
return linkerResult;
}
(0, analyzer_1.default)(programs, entrypointFilePath, topoOrder, context, options?.importOptions);
const program = bundler(programs, entrypointFilePath, topoOrder, context);
return {
ok: true,
program,
files: linkerResult.files,
verboseErrors: linkerResult.verboseErrors
};
}
catch (error) {
context.errors.push(error);
return {
ok: false,
verboseErrors: linkerResult.verboseErrors
};
}
};
exports.default = preprocessFileImports;
//# sourceMappingURL=index.js.map
;