index.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _helperPluginUtils = require("@babel/helper-plugin-utils");
  7. var _core = require("@babel/core");
  8. var _default = (0, _helperPluginUtils.declare)(api => {
  9. api.assertVersion(7);
  10. const surrogate = /[\ud800-\udfff]/g;
  11. const unicodeEscape = /(\\+)u\{([0-9a-fA-F]+)\}/g;
  12. function escape(code) {
  13. let str = code.toString(16);
  14. while (str.length < 4) str = "0" + str;
  15. return "\\u" + str;
  16. }
  17. function replacer(match, backslashes, code) {
  18. if (backslashes.length % 2 === 0) {
  19. return match;
  20. }
  21. const char = String.fromCodePoint(parseInt(code, 16));
  22. const escaped = backslashes.slice(0, -1) + escape(char.charCodeAt(0));
  23. return char.length === 1 ? escaped : escaped + escape(char.charCodeAt(1));
  24. }
  25. function replaceUnicodeEscapes(str) {
  26. return str.replace(unicodeEscape, replacer);
  27. }
  28. function getUnicodeEscape(str) {
  29. let match;
  30. while (match = unicodeEscape.exec(str)) {
  31. if (match[1].length % 2 === 0) continue;
  32. unicodeEscape.lastIndex = 0;
  33. return match[0];
  34. }
  35. return null;
  36. }
  37. return {
  38. name: "transform-unicode-escapes",
  39. visitor: {
  40. Identifier(path) {
  41. const {
  42. node,
  43. key
  44. } = path;
  45. const {
  46. name
  47. } = node;
  48. const replaced = name.replace(surrogate, c => {
  49. return `_u${c.charCodeAt(0).toString(16)}`;
  50. });
  51. if (name === replaced) return;
  52. const str = _core.types.inherits(_core.types.stringLiteral(name), node);
  53. if (key === "key") {
  54. path.replaceWith(str);
  55. return;
  56. }
  57. const {
  58. parentPath,
  59. scope
  60. } = path;
  61. if (parentPath.isMemberExpression({
  62. property: node
  63. }) || parentPath.isOptionalMemberExpression({
  64. property: node
  65. })) {
  66. parentPath.node.computed = true;
  67. path.replaceWith(str);
  68. return;
  69. }
  70. const binding = scope.getBinding(name);
  71. if (binding) {
  72. scope.rename(name, scope.generateUid(replaced));
  73. return;
  74. }
  75. throw path.buildCodeFrameError(`Can't reference '${name}' as a bare identifier`);
  76. },
  77. "StringLiteral|DirectiveLiteral"(path) {
  78. const {
  79. node
  80. } = path;
  81. const {
  82. extra
  83. } = node;
  84. if (extra == null ? void 0 : extra.raw) extra.raw = replaceUnicodeEscapes(extra.raw);
  85. },
  86. TemplateElement(path) {
  87. const {
  88. node,
  89. parentPath
  90. } = path;
  91. const {
  92. value
  93. } = node;
  94. const firstEscape = getUnicodeEscape(value.raw);
  95. if (!firstEscape) return;
  96. const grandParent = parentPath.parentPath;
  97. if (grandParent.isTaggedTemplateExpression()) {
  98. throw path.buildCodeFrameError(`Can't replace Unicode escape '${firstEscape}' inside tagged template literals. You can enable '@babel/plugin-transform-template-literals' to compile them to classic strings.`);
  99. }
  100. value.raw = replaceUnicodeEscapes(value.raw);
  101. }
  102. }
  103. };
  104. });
  105. exports.default = _default;