GSI - Employe Self Service Mobile
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
3.7 KiB

2 months ago
  1. "use strict";
  2. module.exports = codegen;
  3. /**
  4. * Begins generating a function.
  5. * @memberof util
  6. * @param {string[]} functionParams Function parameter names
  7. * @param {string} [functionName] Function name if not anonymous
  8. * @returns {Codegen} Appender that appends code to the function's body
  9. */
  10. function codegen(functionParams, functionName) {
  11. /* istanbul ignore if */
  12. if (typeof functionParams === "string") {
  13. functionName = functionParams;
  14. functionParams = undefined;
  15. }
  16. var body = [];
  17. /**
  18. * Appends code to the function's body or finishes generation.
  19. * @typedef Codegen
  20. * @type {function}
  21. * @param {string|Object.<string,*>} [formatStringOrScope] Format string or, to finish the function, an object of additional scope variables, if any
  22. * @param {...*} [formatParams] Format parameters
  23. * @returns {Codegen|Function} Itself or the generated function if finished
  24. * @throws {Error} If format parameter counts do not match
  25. */
  26. function Codegen(formatStringOrScope) {
  27. // note that explicit array handling below makes this ~50% faster
  28. // finish the function
  29. if (typeof formatStringOrScope !== "string") {
  30. var source = toString();
  31. if (codegen.verbose)
  32. console.log("codegen: " + source); // eslint-disable-line no-console
  33. source = "return " + source;
  34. if (formatStringOrScope) {
  35. var scopeKeys = Object.keys(formatStringOrScope),
  36. scopeParams = new Array(scopeKeys.length + 1),
  37. scopeValues = new Array(scopeKeys.length),
  38. scopeOffset = 0;
  39. while (scopeOffset < scopeKeys.length) {
  40. scopeParams[scopeOffset] = scopeKeys[scopeOffset];
  41. scopeValues[scopeOffset] = formatStringOrScope[scopeKeys[scopeOffset++]];
  42. }
  43. scopeParams[scopeOffset] = source;
  44. return Function.apply(null, scopeParams).apply(null, scopeValues); // eslint-disable-line no-new-func
  45. }
  46. return Function(source)(); // eslint-disable-line no-new-func
  47. }
  48. // otherwise append to body
  49. var formatParams = new Array(arguments.length - 1),
  50. formatOffset = 0;
  51. while (formatOffset < formatParams.length)
  52. formatParams[formatOffset] = arguments[++formatOffset];
  53. formatOffset = 0;
  54. formatStringOrScope = formatStringOrScope.replace(/%([%dfijs])/g, function replace($0, $1) {
  55. var value = formatParams[formatOffset++];
  56. switch ($1) {
  57. case "d": case "f": return String(Number(value));
  58. case "i": return String(Math.floor(value));
  59. case "j": return JSON.stringify(value);
  60. case "s": return String(value);
  61. }
  62. return "%";
  63. });
  64. if (formatOffset !== formatParams.length)
  65. throw Error("parameter count mismatch");
  66. body.push(formatStringOrScope);
  67. return Codegen;
  68. }
  69. function toString(functionNameOverride) {
  70. return "function " + (functionNameOverride || functionName || "") + "(" + (functionParams && functionParams.join(",") || "") + "){\n " + body.join("\n ") + "\n}";
  71. }
  72. Codegen.toString = toString;
  73. return Codegen;
  74. }
  75. /**
  76. * Begins generating a function.
  77. * @memberof util
  78. * @function codegen
  79. * @param {string} [functionName] Function name if not anonymous
  80. * @returns {Codegen} Appender that appends code to the function's body
  81. * @variation 2
  82. */
  83. /**
  84. * When set to `true`, codegen will log generated code to console. Useful for debugging.
  85. * @name util.codegen.verbose
  86. * @type {boolean}
  87. */
  88. codegen.verbose = false;