utils.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.intersection = intersection;
  4. exports.has = has;
  5. exports.resolveKey = resolveKey;
  6. exports.resolveSource = resolveSource;
  7. exports.getImportSource = getImportSource;
  8. exports.getRequireSource = getRequireSource;
  9. exports.createUtilsGetter = createUtilsGetter;
  10. var _core = require("@babel/core");
  11. function intersection(a, b) {
  12. const result = new Set();
  13. a.forEach(v => b.has(v) && result.add(v));
  14. return result;
  15. }
  16. function has(object, key) {
  17. return Object.prototype.hasOwnProperty.call(object, key);
  18. }
  19. function getType(target) {
  20. return Object.prototype.toString.call(target).slice(8, -1);
  21. }
  22. function resolveId(path) {
  23. if (path.isIdentifier() && !path.scope.hasBinding(path.node.name,
  24. /* noGlobals */
  25. true)) {
  26. return path.node.name;
  27. }
  28. const {
  29. deopt
  30. } = path.evaluate();
  31. if (deopt && deopt.isIdentifier()) {
  32. return deopt.node.name;
  33. }
  34. }
  35. function resolveKey(path, computed = false) {
  36. const {
  37. node,
  38. parent,
  39. scope
  40. } = path;
  41. if (path.isStringLiteral()) return node.value;
  42. const {
  43. name
  44. } = node;
  45. const isIdentifier = path.isIdentifier();
  46. if (isIdentifier && !(computed || parent.computed)) return name;
  47. if (computed && path.isMemberExpression() && path.get("object").isIdentifier({
  48. name: "Symbol"
  49. }) && !scope.hasBinding("Symbol",
  50. /* noGlobals */
  51. true)) {
  52. const sym = resolveKey(path.get("property"), path.node.computed);
  53. if (sym) return "Symbol." + sym;
  54. }
  55. if (!isIdentifier || scope.hasBinding(name,
  56. /* noGlobals */
  57. true)) {
  58. const {
  59. value
  60. } = path.evaluate();
  61. if (typeof value === "string") return value;
  62. }
  63. }
  64. function resolveSource(obj) {
  65. if (obj.isMemberExpression() && obj.get("property").isIdentifier({
  66. name: "prototype"
  67. })) {
  68. const id = resolveId(obj.get("object"));
  69. if (id) {
  70. return {
  71. id,
  72. placement: "prototype"
  73. };
  74. }
  75. return {
  76. id: null,
  77. placement: null
  78. };
  79. }
  80. const id = resolveId(obj);
  81. if (id) {
  82. return {
  83. id,
  84. placement: "static"
  85. };
  86. }
  87. const {
  88. value
  89. } = obj.evaluate();
  90. if (value !== undefined) {
  91. return {
  92. id: getType(value),
  93. placement: "prototype"
  94. };
  95. } else if (obj.isRegExpLiteral()) {
  96. return {
  97. id: "RegExp",
  98. placement: "prototype"
  99. };
  100. } else if (obj.isFunction()) {
  101. return {
  102. id: "Function",
  103. placement: "prototype"
  104. };
  105. }
  106. return {
  107. id: null,
  108. placement: null
  109. };
  110. }
  111. function getImportSource({
  112. node
  113. }) {
  114. if (node.specifiers.length === 0) return node.source.value;
  115. }
  116. function getRequireSource({
  117. node
  118. }) {
  119. if (!_core.types.isExpressionStatement(node)) return;
  120. const {
  121. expression
  122. } = node;
  123. const isRequire = _core.types.isCallExpression(expression) && _core.types.isIdentifier(expression.callee) && expression.callee.name === "require" && expression.arguments.length === 1 && _core.types.isStringLiteral(expression.arguments[0]);
  124. if (isRequire) return expression.arguments[0].value;
  125. }
  126. function hoist(node) {
  127. node._blockHoist = 3;
  128. return node;
  129. }
  130. function createUtilsGetter(cache) {
  131. return path => {
  132. const prog = path.findParent(p => p.isProgram());
  133. return {
  134. injectGlobalImport(url) {
  135. cache.storeAnonymous(prog, url, (isScript, source) => {
  136. return isScript ? _core.template.statement.ast`require(${source})` : _core.types.importDeclaration([], source);
  137. });
  138. },
  139. injectNamedImport(url, name, hint = name) {
  140. return cache.storeNamed(prog, url, name, (isScript, source, name) => {
  141. const id = prog.scope.generateUidIdentifier(hint);
  142. return {
  143. node: isScript ? hoist(_core.template.statement.ast`
  144. var ${id} = require(${source}).${name}
  145. `) : _core.types.importDeclaration([_core.types.importSpecifier(id, name)], source),
  146. name: id.name
  147. };
  148. });
  149. },
  150. injectDefaultImport(url, hint = url) {
  151. return cache.storeNamed(prog, url, "default", (isScript, source) => {
  152. const id = prog.scope.generateUidIdentifier(hint);
  153. return {
  154. node: isScript ? hoist(_core.template.statement.ast`var ${id} = require(${source})`) : _core.types.importDeclaration([_core.types.importDefaultSpecifier(id)], source),
  155. name: id.name
  156. };
  157. });
  158. }
  159. };
  160. };
  161. }