master
Sven Slootweg 2 years ago
parent bfe0422ff6
commit 41cb6b101d

@ -3,12 +3,9 @@
const assert = require("assert"); const assert = require("assert");
const types = require("@babel/types"); const types = require("@babel/types");
const template = require("@babel/template").default; const template = require("@babel/template").default;
const splitFilter = require("split-filter");
const unpackExpression = require("./util/unpack-expression");
const templateExpression = require("./util/template-expression"); const templateExpression = require("./util/template-expression");
const NoChange = require("../astformer/actions/no-change"); const NoChange = require("../astformer/actions/no-change");
const printAst = require("../print-ast");
const lazyWrapper = require("./templates/lazy-wrapper"); const lazyWrapper = require("./templates/lazy-wrapper");
const callLazyWrapper = require("./templates/call-lazy-wrapper"); const callLazyWrapper = require("./templates/call-lazy-wrapper");
const objectLiteral = require("./templates/object-literal"); const objectLiteral = require("./templates/object-literal");

@ -4,17 +4,17 @@ const asExpression = require("as-expression");
const assert = require("assert"); const assert = require("assert");
const types = require("@babel/types"); const types = require("@babel/types");
const template = require("@babel/template").default; const template = require("@babel/template").default;
const unpackExpression = require("./util/unpack-expression");
const lazyWrapper = require("./templates/lazy-wrapper"); const lazyWrapper = require("./templates/lazy-wrapper");
const callLazyWrapper = require("./templates/call-lazy-wrapper"); const callLazyWrapper = require("./templates/call-lazy-wrapper");
const templateExpression = require("./util/template-expression");
let tmplFunctionDefinitionUniversal = template(` let tmplFunctionDefinitionUniversal = templateExpression(`
((%%universal%%) => { ((%%universal%%) => {
return %%body%%; return %%body%%;
}) })
`); `);
let tmplFunctionDefinitionWithFormals = template(`( let tmplFunctionDefinitionWithFormals = templateExpression(`(
(%%universal%%) => { (%%universal%%) => {
%%handleArguments%%; %%handleArguments%%;
@ -26,7 +26,7 @@ let tmplHandleArgument = template(`
const %%name%% = $handleArgument(%%nameString%%, %%universal%%, %%defaultArg%%); const %%name%% = $handleArgument(%%nameString%%, %%universal%%, %%defaultArg%%);
`); `);
let tmplFunctionCall = template(` let tmplFunctionCall = templateExpression(`
(%%function%%(%%arg%%)) (%%function%%(%%arg%%))
`); `);
@ -66,44 +66,40 @@ module.exports = {
setContext([ "universal", "formals" ], "identifierType", "define"); setContext([ "universal", "formals" ], "identifierType", "define");
return defer((node) => { return defer((node) => {
return unpackExpression( return functionDefinition({
functionDefinition({ universal: asExpression(() => {
universal: asExpression(() => { if (node.universal != null) {
if (node.universal != null) { assert(node.universal.type === "Identifier");
assert(node.universal.type === "Identifier"); return node.universal.name;
return node.universal.name; }
} }),
}), formals: asExpression(() => {
formals: asExpression(() => { if (node.formals != null) {
if (node.formals != null) { assert(node.formals.type === "NixUnpackedAttributes");
assert(node.formals.type === "NixUnpackedAttributes");
return node.formals.formal.map((formal) => {
return node.formals.formal.map((formal) => { assert(formal.type === "NixUnpackedAttribute");
assert(formal.type === "NixUnpackedAttribute"); assert(formal.name.type === "Identifier");
assert(formal.name.type === "Identifier"); return {
return { name: formal.name.name,
name: formal.name.name, // NOTE: This unwrap-and-rewrap dance is necessary to make out-of-order references work, like in eval-okay-scope-4.nix
// NOTE: This unwrap-and-rewrap dance is necessary to make out-of-order references work, like in eval-okay-scope-4.nix default: (formal.default != null)
default: (formal.default != null) ? lazyWrapper(callLazyWrapper(formal.default))
? lazyWrapper(callLazyWrapper(formal.default)) : undefined
: undefined };
}; });
}); }
} }),
}), body: node.body
body: node.body });
})
);
}); });
}, },
NixFunctionCall: (_node, { defer }) => { NixFunctionCall: (_node, { defer }) => {
return defer((node) => { return defer((node) => {
return unpackExpression( return tmplFunctionCall({
tmplFunctionCall({ function: node.function,
function: node.function, arg: lazyWrapper(node.argument)
arg: lazyWrapper(node.argument) });
})
);
}); });
} }
} }

@ -3,17 +3,8 @@
const assert = require("assert"); const assert = require("assert");
const types = require("@babel/types"); const types = require("@babel/types");
const template = require("@babel/template").default; const template = require("@babel/template").default;
const unreachable = require("@joepie91/unreachable")("jsnix");
const NoChange = require("../astformer/actions/no-change");
const ConsumeNode = require("../astformer/actions/consume-node");
const RemoveNode = require("../astformer/actions/remove-node");
const asExpression = require("as-expression");
const unpackExpression = require("./util/unpack-expression");
const printAst = require("../print-ast");
const templateExpression = require("./util/template-expression");
// FIXME: Auto-generate argument list based on exposed API surface? // FIXME: Auto-generate argument list based on exposed API surface?
let tmplModule = template(` let tmplModule = template(`
@ -22,44 +13,10 @@ let tmplModule = template(`
}; };
`); `);
let tmplObjectDynamic = template(` let tmplIdentifierReference = templateExpression(`(
(() => {
let $$nixJS_object = {};
%%entries%%
return $$nixJS_object;
})()
`);
let tmplObjectDynamicEntry = template(`
if ($$nixJS_object[%%key%%] !== undefined) { throw new Error(\`Duplicate key '\${%%key%%}' in attribute set\`); }
$$nixJS_object[%%key%%] = %%wrappedExpression%%;
`);
let tmplIdentifierReference = template(`(
%%name%%() %%name%%()
)`); )`);
function generateDynamicObject(bindings, recursive) {
let generatedBindings = bindings.map((binding) => {
let wrapper = (recursive)
? tmplLazyWrapperRecursive
: tmplLazyWrapper;
let key = isDynamicBinding(binding)
? binding.attrpath.attr[0]
: binding.attrpath.attr[0].name;
return tmplObjectDynamicEntry({
key: key,
wrappedExpression: wrapper({ expression: binding.expression })
});
});
return tmplObjectDynamic({ entries: generatedBindings.flat() })
}
let trivial = { let trivial = {
name: "trivial-transforms", name: "trivial-transforms",
visitors: { visitors: {
@ -78,7 +35,7 @@ let trivial = {
if (getContext("identifierType") === "define") { if (getContext("identifierType") === "define") {
return types.identifier(node.name); return types.identifier(node.name);
} else { // reference } else { // reference
return unpackExpression(tmplIdentifierReference({ name: node.name })); return tmplIdentifierReference({ name: node.name });
} }
}, },
NixBinaryOperation: (_node, { defer }) => { NixBinaryOperation: (_node, { defer }) => {

@ -1,12 +1,11 @@
"use strict"; "use strict";
const template = require("@babel/template").default; const templateExpression = require("../util/template-expression");
const unpackExpression = require("../util/unpack-expression");
let tmplCallLazy = template(`( let tmplCallLazy = templateExpression(`(
%%wrapper%%() %%wrapper%%()
)`); )`);
module.exports = function callLazyWrapper(wrapper) { module.exports = function callLazyWrapper(wrapper) {
return unpackExpression(tmplCallLazy({ wrapper })); return tmplCallLazy({ wrapper });
}; };

@ -1,15 +1,13 @@
"use strict"; "use strict";
const template = require("@babel/template").default; const templateExpression = require("../util/template-expression");
const unpackExpression = require("../util/unpack-expression"); let tmplLazyWrapper = templateExpression(`(
let tmplLazyWrapper = template(`(
$memoize(() => %%expression%%) $memoize(() => %%expression%%)
)`); )`);
module.exports = function lazyWrapper(expression) { module.exports = function lazyWrapper(expression) {
return unpackExpression(tmplLazyWrapper({ return tmplLazyWrapper({
expression: expression expression: expression
})); });
}; };

Loading…
Cancel
Save