@informalsystems/quint
Version:
Core tool for the Quint specification language
76 lines • 3.05 kB
JavaScript
;
/* ----------------------------------------------------------------------------------
* 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.addNamespaceToDefinition = void 0;
/**
* Recursive addition of namespaces into all names in IR components. To be used in flattening
* to manipulate names of copied definitions.
*
* @author Gabriela Moreira
*
* @module
*/
const IRTransformer_1 = require("./IRTransformer");
/**
* Adds a namespace to a QuintDef and the names inside it, preserving a set of names.
*
* @param def - The QuintDef to add the namespace to.
* @param namespace - The namespace to add.
* @param namesToPreserve - A set of names that should not receive the namespace (e.g. builtin names).
* @returns A new QuintDef with the namespace added to its name and all names inside it.
*/
function addNamespaceToDefinition(def, namespace, namesToPreserve) {
const updater = new Namespacer(namespace, namesToPreserve);
return (0, IRTransformer_1.transformDefinition)(updater, def);
}
exports.addNamespaceToDefinition = addNamespaceToDefinition;
class Namespacer {
constructor(namespace, namesToPreserve) {
this.namespace = namespace;
this.namesToPreserve = namesToPreserve;
}
exitDef(def) {
// FIXME: The current flattener expects `namesToPreserve` to be ignored for def names.
// In the new flattener, we will need to consider it here as well.
// Also, considering it here makes the interface consistent.
// Uncomment the following line when the new flattener is in place:
// if (!this.namesToPreserve.has(def.name)) {
return { ...def, name: namespacedName(this.namespace, def.name) };
}
exitLambda(expr) {
return {
...expr,
params: expr.params.map(p => ({ ...p, name: namespacedName(this.namespace, p.name) })),
};
}
exitName(expr) {
if (!this.namesToPreserve.has(expr.name)) {
return { ...expr, name: namespacedName(this.namespace, expr.name) };
}
return expr;
}
exitApp(expr) {
if (!this.namesToPreserve.has(expr.opcode)) {
return { ...expr, opcode: namespacedName(this.namespace, expr.opcode) };
}
return expr;
}
exitConstType(type) {
if (!this.namesToPreserve.has(type.name)) {
return { ...type, name: namespacedName(this.namespace, type.name) };
}
return type;
}
}
function namespacedName(namespace, name) {
if (name === '_') {
return name;
}
// FIXME(#1111): We shouldn't need to verify `startsWith` if we find a good way to manage namespaces
return namespace && !name.startsWith(`${namespace}::`) ? `${namespace}::${name}` : name;
}
//# sourceMappingURL=namespacer.js.map