index.cjs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. const acorn = require('acorn');
  4. function stripLiteralAcorn(code) {
  5. const FILL = " ";
  6. let result = "";
  7. function fulfill(index) {
  8. if (index > result.length)
  9. result += code.slice(result.length, index).replace(/[^\n]/g, FILL);
  10. }
  11. const tokens = acorn.tokenizer(code, {
  12. ecmaVersion: "latest",
  13. sourceType: "module",
  14. allowHashBang: true,
  15. allowAwaitOutsideFunction: true,
  16. allowImportExportEverywhere: true
  17. });
  18. const inter = tokens[Symbol.iterator]();
  19. while (true) {
  20. const { done, value: token } = inter.next();
  21. if (done)
  22. break;
  23. fulfill(token.start);
  24. if (token.type.label === "string")
  25. result += code[token.start] + FILL.repeat(token.end - token.start - 2) + code[token.end - 1];
  26. else if (token.type.label === "template")
  27. result += FILL.repeat(token.end - token.start);
  28. else
  29. result += code.slice(token.start, token.end);
  30. }
  31. fulfill(code.length);
  32. return result;
  33. }
  34. function createIsLiteralPositionAcorn(code) {
  35. const positionList = [];
  36. const tokens = acorn.tokenizer(code, {
  37. ecmaVersion: "latest",
  38. sourceType: "module",
  39. allowHashBang: true,
  40. allowAwaitOutsideFunction: true,
  41. allowImportExportEverywhere: true,
  42. onComment(_isBlock, _text, start, end) {
  43. positionList.push(start);
  44. positionList.push(end);
  45. }
  46. });
  47. const inter = tokens[Symbol.iterator]();
  48. while (true) {
  49. const { done, value: token } = inter.next();
  50. if (done)
  51. break;
  52. if (token.type.label === "string") {
  53. positionList.push(token.start + 1);
  54. positionList.push(token.end - 1);
  55. } else if (token.type.label === "template") {
  56. positionList.push(token.start);
  57. positionList.push(token.end);
  58. }
  59. }
  60. return (position) => {
  61. const i = binarySearch(positionList, (v) => position < v);
  62. return (i - 1) % 2 === 0;
  63. };
  64. }
  65. function binarySearch(array, pred) {
  66. let low = -1;
  67. let high = array.length;
  68. while (1 + low < high) {
  69. const mid = low + (high - low >> 1);
  70. if (pred(array[mid]))
  71. high = mid;
  72. else
  73. low = mid;
  74. }
  75. return high;
  76. }
  77. const multilineCommentsRE = /\/\*.*?\*\//gms;
  78. const singlelineCommentsRE = /(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/gm;
  79. const templateLiteralRE = /\$\{(\s*(?:(?!\$\{).|\n|\r)*?\s*)\}/g;
  80. const quotesRE = [
  81. /(["'`])((?:\\\1|(?!\1)|.|\r)*?)\1/gm,
  82. /([`])((?:\\\1|(?!\1)|.|\n|\r)*?)\1/gm
  83. ];
  84. function stripLiteralRegex(code) {
  85. code = code.replace(multilineCommentsRE, (s) => " ".repeat(s.length)).replace(singlelineCommentsRE, (s) => " ".repeat(s.length));
  86. let expanded = code;
  87. for (let i = 0; i < 16; i++) {
  88. const before = expanded;
  89. expanded = expanded.replace(templateLiteralRE, "` $1`");
  90. if (expanded === before)
  91. break;
  92. }
  93. quotesRE.forEach((re) => {
  94. expanded = expanded.replace(re, (s, quote, body, index) => {
  95. code = code.slice(0, index + 1) + " ".repeat(s.length - 2) + code.slice(index + s.length - 1);
  96. return quote + " ".repeat(s.length - 2) + quote;
  97. });
  98. });
  99. return code;
  100. }
  101. function stripLiteral(code) {
  102. try {
  103. return stripLiteralAcorn(code);
  104. } catch (e) {
  105. return stripLiteralRegex(code);
  106. }
  107. }
  108. exports.createIsLiteralPositionAcorn = createIsLiteralPositionAcorn;
  109. exports.stripLiteral = stripLiteral;
  110. exports.stripLiteralAcorn = stripLiteralAcorn;
  111. exports.stripLiteralRegex = stripLiteralRegex;