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;
|