UNPKG

@0ria/constant-folding

Version:
139 lines (112 loc) 4.63 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: constant-folding.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: constant-folding.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>// See https://github.com/babel/minify/tree/master/packages/babel-plugin-minify-constant-folding const fs = require("fs"); const deb = require('../src/deb.js'); const escodegen = require("escodegen"); const espree = require("espree"); const estraverse = require("estraverse"); "use strict"; module.exports = constantFolding; /** * This function gets passed by a Node and depending on its type will perform * different operations. * @param {Obect} elem Single subNode * @returns {*} Return single element from passed Node */ function getValues(elem) { let types = { 'Literal' : () => {return elem.raw}, 'Identifier' : () => {return elem.name}, 'ArrayExpression' : () => {return `${elem.elements.map(l => getValues(l))}`}, 'BinaryExpression' : () => {return `${eval(`${elem.left.raw} ${elem.operator} ${elem.right.raw}`)}`} } return types[elem.type](); } /** * This function gets passed two arguments and perform a transformation in the node * depending different parameters. Then it creates a new node object that will substitute * the passed one. * @param {Object} n Node object in which constant folding will be applied * @param {*} args Possible arguments this node has ex: [a].concat([b]), [b] are the args here */ function transNode(n, args) { let argString = "" let auxstring = ""; let a = n.expression; if (args) { a = n.expression.callee; argString += `(${(args) ? args.map(arg => getValues(arg)) : ''})`; } if (a.property.type == 'Literal') auxString = `[${a.object.elements.map(el => getValues(el))}][${getValues(a.property)}]` + argString; else auxString = `[${a.object.elements.map(el => getValues(el))}].${getValues(a.property)}` + argString; n.expression = espree.parse(eval(auxString)).body[0].expression; } /** * This Function takes a Node of type BinaryExpression and perform constant Folding on it * @param {Object} n Node with a type of BinaryExpression */ function transLiteralNode(n) { n.value = Number(getValues(n)); n.raw = String(n.value); n.type = 'Literal'; delete n.left; delete n.rigth; } /** * This function get passed some code and then it forms an AST tree with it. * After it traverses the tree doing constant folding in different nodes in * which it is possible to perform it * @param {string} code The javascript input code * @returns {string} Generated js code from the resultant tree */ function constantFolding(code) { let ast = espree.parse(code, {ecmaVersion: espree.latestEcmaVersion}); estraverse.traverse(ast, { leave: function(node, parent) { if (node.type == 'ExpressionStatement' &amp;&amp; node.expression.type == 'CallExpression' &amp;&amp; node.expression.callee.object.type == 'ArrayExpression') { transNode(node, node.expression.arguments); } if (node.type == 'ExpressionStatement' &amp;&amp; node.expression.type == 'MemberExpression' &amp;&amp; node.expression.object.type == 'ArrayExpression') { transNode(node); } if(node.type == 'BinaryExpression' &amp;&amp; node.left.type == 'Literal' &amp;&amp; node.right.type == 'Literal') { transLiteralNode(node); } } }); //deb(ast); return escodegen.generate(ast); }</code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#constantFolding">constantFolding</a></li><li><a href="global.html#getValues">getValues</a></li><li><a href="global.html#transLiteralNode">transLiteralNode</a></li><li><a href="global.html#transNode">transNode</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 3.6.10</a> on Thu Mar 10 2022 20:48:02 GMT+0000 (Coordinated Universal Time) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>