diff options
| author | Shipwreckt <me@shipwreckt.co.uk> | 2025-10-31 20:02:14 +0000 |
|---|---|---|
| committer | Shipwreckt <me@shipwreckt.co.uk> | 2025-10-31 20:02:14 +0000 |
| commit | 7a52ddeba2a68388b544f529d2d92104420f77b0 (patch) | |
| tree | 15ddd47457a2cb4a96060747437d36474e4f6b4e /node_modules/nunjucks/src/transformer.js | |
| parent | 53d6ae2b5568437afa5e4995580a3fb679b7b91b (diff) | |
Changed from static to 11ty!
Diffstat (limited to 'node_modules/nunjucks/src/transformer.js')
| -rw-r--r-- | node_modules/nunjucks/src/transformer.js | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/node_modules/nunjucks/src/transformer.js b/node_modules/nunjucks/src/transformer.js new file mode 100644 index 0000000..b11e91c --- /dev/null +++ b/node_modules/nunjucks/src/transformer.js @@ -0,0 +1,166 @@ +'use strict'; + +var nodes = require('./nodes'); +var lib = require('./lib'); +var sym = 0; +function gensym() { + return 'hole_' + sym++; +} + +// copy-on-write version of map +function mapCOW(arr, func) { + var res = null; + for (var i = 0; i < arr.length; i++) { + var item = func(arr[i]); + if (item !== arr[i]) { + if (!res) { + res = arr.slice(); + } + res[i] = item; + } + } + return res || arr; +} +function walk(ast, func, depthFirst) { + if (!(ast instanceof nodes.Node)) { + return ast; + } + if (!depthFirst) { + var astT = func(ast); + if (astT && astT !== ast) { + return astT; + } + } + if (ast instanceof nodes.NodeList) { + var children = mapCOW(ast.children, function (node) { + return walk(node, func, depthFirst); + }); + if (children !== ast.children) { + ast = new nodes[ast.typename](ast.lineno, ast.colno, children); + } + } else if (ast instanceof nodes.CallExtension) { + var args = walk(ast.args, func, depthFirst); + var contentArgs = mapCOW(ast.contentArgs, function (node) { + return walk(node, func, depthFirst); + }); + if (args !== ast.args || contentArgs !== ast.contentArgs) { + ast = new nodes[ast.typename](ast.extName, ast.prop, args, contentArgs); + } + } else { + var props = ast.fields.map(function (field) { + return ast[field]; + }); + var propsT = mapCOW(props, function (prop) { + return walk(prop, func, depthFirst); + }); + if (propsT !== props) { + ast = new nodes[ast.typename](ast.lineno, ast.colno); + propsT.forEach(function (prop, i) { + ast[ast.fields[i]] = prop; + }); + } + } + return depthFirst ? func(ast) || ast : ast; +} +function depthWalk(ast, func) { + return walk(ast, func, true); +} +function _liftFilters(node, asyncFilters, prop) { + var children = []; + var walked = depthWalk(prop ? node[prop] : node, function (descNode) { + var symbol; + if (descNode instanceof nodes.Block) { + return descNode; + } else if (descNode instanceof nodes.Filter && lib.indexOf(asyncFilters, descNode.name.value) !== -1 || descNode instanceof nodes.CallExtensionAsync) { + symbol = new nodes.Symbol(descNode.lineno, descNode.colno, gensym()); + children.push(new nodes.FilterAsync(descNode.lineno, descNode.colno, descNode.name, descNode.args, symbol)); + } + return symbol; + }); + if (prop) { + node[prop] = walked; + } else { + node = walked; + } + if (children.length) { + children.push(node); + return new nodes.NodeList(node.lineno, node.colno, children); + } else { + return node; + } +} +function liftFilters(ast, asyncFilters) { + return depthWalk(ast, function (node) { + if (node instanceof nodes.Output) { + return _liftFilters(node, asyncFilters); + } else if (node instanceof nodes.Set) { + return _liftFilters(node, asyncFilters, 'value'); + } else if (node instanceof nodes.For) { + return _liftFilters(node, asyncFilters, 'arr'); + } else if (node instanceof nodes.If) { + return _liftFilters(node, asyncFilters, 'cond'); + } else if (node instanceof nodes.CallExtension) { + return _liftFilters(node, asyncFilters, 'args'); + } else { + return undefined; + } + }); +} +function liftSuper(ast) { + return walk(ast, function (blockNode) { + if (!(blockNode instanceof nodes.Block)) { + return; + } + var hasSuper = false; + var symbol = gensym(); + blockNode.body = walk(blockNode.body, function (node) { + // eslint-disable-line consistent-return + if (node instanceof nodes.FunCall && node.name.value === 'super') { + hasSuper = true; + return new nodes.Symbol(node.lineno, node.colno, symbol); + } + }); + if (hasSuper) { + blockNode.body.children.unshift(new nodes.Super(0, 0, blockNode.name, new nodes.Symbol(0, 0, symbol))); + } + }); +} +function convertStatements(ast) { + return depthWalk(ast, function (node) { + if (!(node instanceof nodes.If) && !(node instanceof nodes.For)) { + return undefined; + } + var async = false; + walk(node, function (child) { + if (child instanceof nodes.FilterAsync || child instanceof nodes.IfAsync || child instanceof nodes.AsyncEach || child instanceof nodes.AsyncAll || child instanceof nodes.CallExtensionAsync) { + async = true; + // Stop iterating by returning the node + return child; + } + return undefined; + }); + if (async) { + if (node instanceof nodes.If) { + return new nodes.IfAsync(node.lineno, node.colno, node.cond, node.body, node.else_); + } else if (node instanceof nodes.For && !(node instanceof nodes.AsyncAll)) { + return new nodes.AsyncEach(node.lineno, node.colno, node.arr, node.name, node.body, node.else_); + } + } + return undefined; + }); +} +function cps(ast, asyncFilters) { + return convertStatements(liftSuper(liftFilters(ast, asyncFilters))); +} +function transform(ast, asyncFilters) { + return cps(ast, asyncFilters || []); +} + +// var parser = require('./parser'); +// var src = 'hello {% foo %}{% endfoo %} end'; +// var ast = transform(parser.parse(src, [new FooExtension()]), ['bar']); +// nodes.printNodes(ast); + +module.exports = { + transform: transform +};
\ No newline at end of file |
