You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
45 lines
1.6 KiB
JavaScript
45 lines
1.6 KiB
JavaScript
"use strict";
|
|
|
|
const unreachable = require("@joepie91/unreachable");
|
|
const assert = require("assert");
|
|
const splitFilter = require("split-filter");
|
|
const _nixTypes = require("./util/nix-types");
|
|
|
|
function isValidBodyAttribute(binding) {
|
|
assert(binding.attrpath.type === "NixAttributePath");
|
|
assert(binding.attrpath.attr.length > 0);
|
|
assert(binding.attrpath.attr[0].type === "NixIdentifier");
|
|
|
|
if (binding.attrpath.attr[0].name === "body") {
|
|
if (binding.attrpath.attr.length > 1) {
|
|
throw unreachable("attribute paths should have been desugared");
|
|
} else {
|
|
return true;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
name: "desugar-let-attribute-set",
|
|
visitors: {
|
|
NixLetAttributeSet: (node) => {
|
|
// We save a bunch of complexity here by directly translating to a recursive attribute set instead of `let..in`; our JS representation of `let..in` is *functionally* identical to how a LetAttributeSet works. We just use a different attribute name to represent the returned evaluation.
|
|
|
|
let [ bodyBindings, actualBindings ] = splitFilter(node.binding, (binding) => isValidBodyAttribute(binding));
|
|
|
|
if (bodyBindings.length === 0) {
|
|
// TODO: Display source code position + snippet
|
|
// FIXME: It's possible to specify the `body` with a dynamic key; this means that we can't actually do a compile-time check here, at least not reliably, and we need to insert a runtime guard if the compile-time check fails and dynamic attributes are specified
|
|
throw new Error(`Missing required 'body' attribute in LetAttributeSet`);
|
|
} else {
|
|
return _nixTypes.JSNixLet(
|
|
actualBindings,
|
|
bodyBindings[0].expression
|
|
);
|
|
}
|
|
}
|
|
}
|
|
};
|