@informalsystems/quint
Version:
Core tool for the Quint specification language
81 lines • 2.9 kB
JavaScript
"use strict";
/* ----------------------------------------------------------------------------------
* Copyright 2023 Informal Systems
* Licensed under the Apache License, Version 2.0.
* See LICENSE in the project root for license information.
* --------------------------------------------------------------------------------- */
Object.defineProperty(exports, "__esModule", { value: true });
exports.unshadowNames = void 0;
/**
* Renamer for shadowed names.
*
* @author Gabriela Moreira
*
* @module
*/
const IRTransformer_1 = require("../ir/IRTransformer");
/**
* Replace all names with unique names, to avoid shadowing.
* - Lambda parameters are renamed to `<name>_<lambda-id>`
* - Nested definitions (from let expressions) are renamed to `<name>_<let-id>` only if they shadow another name
*
* @param module The module to unshadow
* @param lookupTable The lookup table with the module's name references
*
* @returns The module with no shadowed names
*/
function unshadowNames(module, lookupTable) {
const transformer = new Unshadower(lookupTable);
return (0, IRTransformer_1.transformModule)(transformer, module);
}
exports.unshadowNames = unshadowNames;
class Unshadower {
constructor(lookupTable) {
this.nestedNames = new Map();
this.lookupTable = lookupTable;
}
enterLambda(lambda) {
const newParams = lambda.params.map(p => {
// Ideally, we should only rename if `this.lookupTable.get(p.id)?.shadowing` is true, as we do in let.
// However, this currently is a problem with Apalache, see issue #1443.
const newName = `${p.name}_${lambda.id}`;
this.nestedNames.set(p.id, newName);
return { ...p, name: newName };
});
return { ...lambda, params: newParams };
}
enterLet(expr) {
if (!this.lookupTable.get(expr.opdef.id)?.shadowing) {
// nothing to do
return expr;
}
const newName = `${expr.opdef.name}_${expr.id}`;
this.nestedNames.set(expr.opdef.id, newName);
return { ...expr, opdef: { ...expr.opdef, name: newName } };
}
enterName(expr) {
const def = this.lookupTable.get(expr.id);
if (!def) {
return expr;
}
const newName = this.nestedNames.get(def.id);
if (newName) {
this.lookupTable.set(expr.id, { ...def, name: newName });
return { ...expr, name: newName };
}
return expr;
}
enterApp(expr) {
const def = this.lookupTable.get(expr.id);
if (!def) {
return expr;
}
const newName = this.nestedNames.get(def.id);
if (newName) {
this.lookupTable.set(expr.id, { ...def, name: newName });
return { ...expr, opcode: newName };
}
return expr;
}
}
//# sourceMappingURL=unshadower.js.map