code.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = void 0;
  4. // eslint-disable-next-line @typescript-eslint/no-extraneous-class
  5. class _CodeOrName {
  6. }
  7. exports._CodeOrName = _CodeOrName;
  8. exports.IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
  9. class Name extends _CodeOrName {
  10. constructor(s) {
  11. super();
  12. if (!exports.IDENTIFIER.test(s))
  13. throw new Error("CodeGen: name must be a valid identifier");
  14. this.str = s;
  15. }
  16. toString() {
  17. return this.str;
  18. }
  19. emptyStr() {
  20. return false;
  21. }
  22. get names() {
  23. return { [this.str]: 1 };
  24. }
  25. }
  26. exports.Name = Name;
  27. class _Code extends _CodeOrName {
  28. constructor(code) {
  29. super();
  30. this._items = typeof code === "string" ? [code] : code;
  31. }
  32. toString() {
  33. return this.str;
  34. }
  35. emptyStr() {
  36. if (this._items.length > 1)
  37. return false;
  38. const item = this._items[0];
  39. return item === "" || item === '""';
  40. }
  41. get str() {
  42. var _a;
  43. return ((_a = this._str) !== null && _a !== void 0 ? _a : (this._str = this._items.reduce((s, c) => `${s}${c}`, "")));
  44. }
  45. get names() {
  46. var _a;
  47. return ((_a = this._names) !== null && _a !== void 0 ? _a : (this._names = this._items.reduce((names, c) => {
  48. if (c instanceof Name)
  49. names[c.str] = (names[c.str] || 0) + 1;
  50. return names;
  51. }, {})));
  52. }
  53. }
  54. exports._Code = _Code;
  55. exports.nil = new _Code("");
  56. function _(strs, ...args) {
  57. const code = [strs[0]];
  58. let i = 0;
  59. while (i < args.length) {
  60. addCodeArg(code, args[i]);
  61. code.push(strs[++i]);
  62. }
  63. return new _Code(code);
  64. }
  65. exports._ = _;
  66. const plus = new _Code("+");
  67. function str(strs, ...args) {
  68. const expr = [safeStringify(strs[0])];
  69. let i = 0;
  70. while (i < args.length) {
  71. expr.push(plus);
  72. addCodeArg(expr, args[i]);
  73. expr.push(plus, safeStringify(strs[++i]));
  74. }
  75. optimize(expr);
  76. return new _Code(expr);
  77. }
  78. exports.str = str;
  79. function addCodeArg(code, arg) {
  80. if (arg instanceof _Code)
  81. code.push(...arg._items);
  82. else if (arg instanceof Name)
  83. code.push(arg);
  84. else
  85. code.push(interpolate(arg));
  86. }
  87. exports.addCodeArg = addCodeArg;
  88. function optimize(expr) {
  89. let i = 1;
  90. while (i < expr.length - 1) {
  91. if (expr[i] === plus) {
  92. const res = mergeExprItems(expr[i - 1], expr[i + 1]);
  93. if (res !== undefined) {
  94. expr.splice(i - 1, 3, res);
  95. continue;
  96. }
  97. expr[i++] = "+";
  98. }
  99. i++;
  100. }
  101. }
  102. function mergeExprItems(a, b) {
  103. if (b === '""')
  104. return a;
  105. if (a === '""')
  106. return b;
  107. if (typeof a == "string") {
  108. if (b instanceof Name || a[a.length - 1] !== '"')
  109. return;
  110. if (typeof b != "string")
  111. return `${a.slice(0, -1)}${b}"`;
  112. if (b[0] === '"')
  113. return a.slice(0, -1) + b.slice(1);
  114. return;
  115. }
  116. if (typeof b == "string" && b[0] === '"' && !(a instanceof Name))
  117. return `"${a}${b.slice(1)}`;
  118. return;
  119. }
  120. function strConcat(c1, c2) {
  121. return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str `${c1}${c2}`;
  122. }
  123. exports.strConcat = strConcat;
  124. // TODO do not allow arrays here
  125. function interpolate(x) {
  126. return typeof x == "number" || typeof x == "boolean" || x === null
  127. ? x
  128. : safeStringify(Array.isArray(x) ? x.join(",") : x);
  129. }
  130. function stringify(x) {
  131. return new _Code(safeStringify(x));
  132. }
  133. exports.stringify = stringify;
  134. function safeStringify(x) {
  135. return JSON.stringify(x)
  136. .replace(/\u2028/g, "\\u2028")
  137. .replace(/\u2029/g, "\\u2029");
  138. }
  139. exports.safeStringify = safeStringify;
  140. function getProperty(key) {
  141. return typeof key == "string" && exports.IDENTIFIER.test(key) ? new _Code(`.${key}`) : _ `[${key}]`;
  142. }
  143. exports.getProperty = getProperty;
  144. //Does best effort to format the name properly
  145. function getEsmExportName(key) {
  146. if (typeof key == "string" && exports.IDENTIFIER.test(key)) {
  147. return new _Code(`${key}`);
  148. }
  149. throw new Error(`CodeGen: invalid export name: ${key}, use explicit $id name mapping`);
  150. }
  151. exports.getEsmExportName = getEsmExportName;
  152. function regexpCode(rx) {
  153. return new _Code(rx.toString());
  154. }
  155. exports.regexpCode = regexpCode;
  156. //# sourceMappingURL=code.js.map