| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 | "use strict";module.exports = codegen;/** * Begins generating a function. * @memberof util * @param {string[]} functionParams Function parameter names * @param {string} [functionName] Function name if not anonymous * @returns {Codegen} Appender that appends code to the function's body */function codegen(functionParams, functionName) {    /* istanbul ignore if */    if (typeof functionParams === "string") {        functionName = functionParams;        functionParams = undefined;    }    var body = [];    /**     * Appends code to the function's body or finishes generation.     * @typedef Codegen     * @type {function}     * @param {string|Object.<string,*>} [formatStringOrScope] Format string or, to finish the function, an object of additional scope variables, if any     * @param {...*} [formatParams] Format parameters     * @returns {Codegen|Function} Itself or the generated function if finished     * @throws {Error} If format parameter counts do not match     */    function Codegen(formatStringOrScope) {        // note that explicit array handling below makes this ~50% faster        // finish the function        if (typeof formatStringOrScope !== "string") {            var source = toString();            if (codegen.verbose)                console.log("codegen: " + source); // eslint-disable-line no-console            source = "return " + source;            if (formatStringOrScope) {                var scopeKeys   = Object.keys(formatStringOrScope),                    scopeParams = new Array(scopeKeys.length + 1),                    scopeValues = new Array(scopeKeys.length),                    scopeOffset = 0;                while (scopeOffset < scopeKeys.length) {                    scopeParams[scopeOffset] = scopeKeys[scopeOffset];                    scopeValues[scopeOffset] = formatStringOrScope[scopeKeys[scopeOffset++]];                }                scopeParams[scopeOffset] = source;                return Function.apply(null, scopeParams).apply(null, scopeValues); // eslint-disable-line no-new-func            }            return Function(source)(); // eslint-disable-line no-new-func        }        // otherwise append to body        var formatParams = new Array(arguments.length - 1),            formatOffset = 0;        while (formatOffset < formatParams.length)            formatParams[formatOffset] = arguments[++formatOffset];        formatOffset = 0;        formatStringOrScope = formatStringOrScope.replace(/%([%dfijs])/g, function replace($0, $1) {            var value = formatParams[formatOffset++];            switch ($1) {                case "d": case "f": return String(Number(value));                case "i": return String(Math.floor(value));                case "j": return JSON.stringify(value);                case "s": return String(value);            }            return "%";        });        if (formatOffset !== formatParams.length)            throw Error("parameter count mismatch");        body.push(formatStringOrScope);        return Codegen;    }    function toString(functionNameOverride) {        return "function " + (functionNameOverride || functionName || "") + "(" + (functionParams && functionParams.join(",") || "") + "){\n  " + body.join("\n  ") + "\n}";    }    Codegen.toString = toString;    return Codegen;}/** * Begins generating a function. * @memberof util * @function codegen * @param {string} [functionName] Function name if not anonymous * @returns {Codegen} Appender that appends code to the function's body * @variation 2 *//** * When set to `true`, codegen will log generated code to console. Useful for debugging. * @name util.codegen.verbose * @type {boolean} */codegen.verbose = false;
 |