UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

95 lines 5.2 kB
"use strict"; /* ---------------------------------------------------------------------------------- * Copyright 2023 Informal Systems * Licensed under the Apache License, Version 2.0. * See LICENSE in the project root for license information. * --------------------------------------------------------------------------------- */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.flattenModules = void 0; /** * Flattening for modules, replacing instances, imports and exports with definitions referred by the module. * * @author Gabriela Moreira * * @module */ const assert_1 = __importDefault(require("assert")); const IRprinting_1 = require("../ir/IRprinting"); const quintIr_1 = require("../ir/quintIr"); const quintParserFrontend_1 = require("../parsing/quintParserFrontend"); const aliasInliner_1 = require("../types/aliasInliner"); const flattener_1 = require("./flattener"); const instanceFlattener_1 = require("./instanceFlattener"); const unshadower_1 = require("../names/unshadower"); const quintError_1 = require("../quintError"); /** * Flatten an array of modules, replacing instances, imports and exports with * their definitions and inlining type aliases. * * @param modules The modules to flatten * @param table The lookup table to for all referred names * @param idGenerator The id generator to use for new definitions; should be the same as used for parsing * @param sourceMap The source map for all modules involved * @param analysisOutput The analysis output for all modules involved * * @returns An object containing the flattened modules, flattened lookup table and flattened analysis output */ function flattenModules(modules, table, idGenerator, sourceMap, analysisOutput) { // FIXME: use copies of parameters so the original objects are not mutated. // This is not a problem atm, but might be in the future. // Use unique names when there is shadowing const modulesWithUniqueNames = modules.map(m => (0, unshadower_1.unshadowNames)(m, table)); // Inline type aliases const inlined = (0, aliasInliner_1.inlineTypeAliases)(modulesWithUniqueNames, table, analysisOutput); const modulesByName = new Map(inlined.modules.map(m => [m.name, m])); // Mutable values, updated on every iteration const flattenedAnalysis = inlined.analysisOutput; const modulesQueue = inlined.modules; // Mutable references, updated on every iteration let flattenedModules = []; let flattenedTable = inlined.table; while (modulesQueue.length > 0) { const module = modulesQueue.shift(); // First, flatten imports and exports const moduleAfterFirstFlattening = (0, flattener_1.flattenModule)(module, modulesByName, flattenedTable); // Then, flatten instances, replacing them with imports const instancedModules = (0, instanceFlattener_1.flattenInstances)(moduleAfterFirstFlattening, modulesByName, flattenedTable, idGenerator, sourceMap, flattenedAnalysis); // Get an updated lookup table including references for the instanced modules. For that, use all the modules that // were flattened so far, plus the instanced modules. const intermediateTable = resolveNamesOrThrow(flattenedModules.concat(instancedModules), sourceMap).table; // Flatten the instanced modules, removing the added imports. instancedModules.forEach(m => { const flat = (0, flattener_1.flattenModule)(m, modulesByName, intermediateTable); flattenedModules.push(flat); // Update the index that is going to be used in next iterations modulesByName.set(m.name, flat); }); // Finally, get an updated lookup table and a toposorted version of the definitions. For that, we combine the // modules that were flattened so far, plus the modules that still have to be flattened (queue). We need to do this // for the modules in the queue as well since they might also refer to definitions that had their ids changed by the // instance flattener. const result = resolveNamesOrThrow(flattenedModules.concat(modulesQueue), sourceMap); flattenedModules = result.modules.slice(0, flattenedModules.length); flattenedTable = result.table; } // FIXME: Ideally we should do this via the type system (0, assert_1.default)(flattenedModules.every(m => m.declarations.every(quintIr_1.isDef))); return { flattenedModules: flattenedModules, flattenedTable, flattenedAnalysis, }; } exports.flattenModules = flattenModules; function resolveNamesOrThrow(modules, sourceMap) { const result = (0, quintParserFrontend_1.parsePhase3importAndNameResolution)({ modules, sourceMap, errors: [] }); if (result.errors.length > 0) { modules.forEach(m => console.log((0, IRprinting_1.moduleToString)(m))); throw new Error('Internal error while flattening ' + result.errors.map(quintError_1.quintErrorToString)); } return result; } //# sourceMappingURL=fullFlattener.js.map