web 3d图形渲染器
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.

367 lines
11 KiB

  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.rewriteModuleStatementsAndPrepareHeader = rewriteModuleStatementsAndPrepareHeader;
  6. exports.ensureStatementsHoisted = ensureStatementsHoisted;
  7. exports.wrapInterop = wrapInterop;
  8. exports.buildNamespaceInitStatements = buildNamespaceInitStatements;
  9. Object.defineProperty(exports, "isModule", {
  10. enumerable: true,
  11. get: function () {
  12. return _helperModuleImports.isModule;
  13. }
  14. });
  15. Object.defineProperty(exports, "rewriteThis", {
  16. enumerable: true,
  17. get: function () {
  18. return _rewriteThis.default;
  19. }
  20. });
  21. Object.defineProperty(exports, "hasExports", {
  22. enumerable: true,
  23. get: function () {
  24. return _normalizeAndLoadMetadata.hasExports;
  25. }
  26. });
  27. Object.defineProperty(exports, "isSideEffectImport", {
  28. enumerable: true,
  29. get: function () {
  30. return _normalizeAndLoadMetadata.isSideEffectImport;
  31. }
  32. });
  33. Object.defineProperty(exports, "getModuleName", {
  34. enumerable: true,
  35. get: function () {
  36. return _getModuleName.default;
  37. }
  38. });
  39. var t = _interopRequireWildcard(require("@babel/types"));
  40. var _template = _interopRequireDefault(require("@babel/template"));
  41. var _helperModuleImports = require("@babel/helper-module-imports");
  42. var _rewriteThis = _interopRequireDefault(require("./rewrite-this"));
  43. var _rewriteLiveReferences = _interopRequireDefault(require("./rewrite-live-references"));
  44. var _normalizeAndLoadMetadata = _interopRequireWildcard(require("./normalize-and-load-metadata"));
  45. var _getModuleName = _interopRequireDefault(require("./get-module-name"));
  46. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  47. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
  48. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  49. const assert = require("assert");
  50. function rewriteModuleStatementsAndPrepareHeader(path, {
  51. loose,
  52. exportName,
  53. strict,
  54. allowTopLevelThis,
  55. strictMode,
  56. noInterop,
  57. lazy,
  58. esNamespaceOnly,
  59. constantReexports = loose,
  60. enumerableModuleMeta = loose
  61. }) {
  62. assert((0, _helperModuleImports.isModule)(path), "Cannot process module statements in a script");
  63. path.node.sourceType = "script";
  64. const meta = (0, _normalizeAndLoadMetadata.default)(path, exportName, {
  65. noInterop,
  66. initializeReexports: constantReexports,
  67. lazy,
  68. esNamespaceOnly
  69. });
  70. if (!allowTopLevelThis) {
  71. (0, _rewriteThis.default)(path);
  72. }
  73. (0, _rewriteLiveReferences.default)(path, meta);
  74. if (strictMode !== false) {
  75. const hasStrict = path.node.directives.some(directive => {
  76. return directive.value.value === "use strict";
  77. });
  78. if (!hasStrict) {
  79. path.unshiftContainer("directives", t.directive(t.directiveLiteral("use strict")));
  80. }
  81. }
  82. const headers = [];
  83. if ((0, _normalizeAndLoadMetadata.hasExports)(meta) && !strict) {
  84. headers.push(buildESModuleHeader(meta, enumerableModuleMeta));
  85. }
  86. const nameList = buildExportNameListDeclaration(path, meta);
  87. if (nameList) {
  88. meta.exportNameListName = nameList.name;
  89. headers.push(nameList.statement);
  90. }
  91. headers.push(...buildExportInitializationStatements(path, meta, constantReexports));
  92. return {
  93. meta,
  94. headers
  95. };
  96. }
  97. function ensureStatementsHoisted(statements) {
  98. statements.forEach(header => {
  99. header._blockHoist = 3;
  100. });
  101. }
  102. function wrapInterop(programPath, expr, type) {
  103. if (type === "none") {
  104. return null;
  105. }
  106. let helper;
  107. if (type === "default") {
  108. helper = "interopRequireDefault";
  109. } else if (type === "namespace") {
  110. helper = "interopRequireWildcard";
  111. } else {
  112. throw new Error(`Unknown interop: ${type}`);
  113. }
  114. return t.callExpression(programPath.hub.addHelper(helper), [expr]);
  115. }
  116. function buildNamespaceInitStatements(metadata, sourceMetadata, constantReexports = false) {
  117. const statements = [];
  118. let srcNamespace = t.identifier(sourceMetadata.name);
  119. if (sourceMetadata.lazy) srcNamespace = t.callExpression(srcNamespace, []);
  120. for (const localName of sourceMetadata.importsNamespace) {
  121. if (localName === sourceMetadata.name) continue;
  122. statements.push(_template.default.statement`var NAME = SOURCE;`({
  123. NAME: localName,
  124. SOURCE: t.cloneNode(srcNamespace)
  125. }));
  126. }
  127. if (constantReexports) {
  128. statements.push(...buildReexportsFromMeta(metadata, sourceMetadata, true));
  129. }
  130. for (const exportName of sourceMetadata.reexportNamespace) {
  131. statements.push((sourceMetadata.lazy ? _template.default.statement`
  132. Object.defineProperty(EXPORTS, "NAME", {
  133. enumerable: true,
  134. get: function() {
  135. return NAMESPACE;
  136. }
  137. });
  138. ` : _template.default.statement`EXPORTS.NAME = NAMESPACE;`)({
  139. EXPORTS: metadata.exportName,
  140. NAME: exportName,
  141. NAMESPACE: t.cloneNode(srcNamespace)
  142. }));
  143. }
  144. if (sourceMetadata.reexportAll) {
  145. const statement = buildNamespaceReexport(metadata, t.cloneNode(srcNamespace), constantReexports);
  146. statement.loc = sourceMetadata.reexportAll.loc;
  147. statements.push(statement);
  148. }
  149. return statements;
  150. }
  151. const ReexportTemplate = {
  152. constant: _template.default.statement`EXPORTS.EXPORT_NAME = NAMESPACE_IMPORT;`,
  153. constantComputed: _template.default.statement`EXPORTS["EXPORT_NAME"] = NAMESPACE_IMPORT;`,
  154. spec: (0, _template.default)`
  155. Object.defineProperty(EXPORTS, "EXPORT_NAME", {
  156. enumerable: true,
  157. get: function() {
  158. return NAMESPACE_IMPORT;
  159. },
  160. });
  161. `
  162. };
  163. const buildReexportsFromMeta = (meta, metadata, constantReexports) => {
  164. const namespace = metadata.lazy ? t.callExpression(t.identifier(metadata.name), []) : t.identifier(metadata.name);
  165. const {
  166. stringSpecifiers
  167. } = meta;
  168. return Array.from(metadata.reexports, ([exportName, importName]) => {
  169. let NAMESPACE_IMPORT;
  170. if (stringSpecifiers.has(importName)) {
  171. NAMESPACE_IMPORT = t.memberExpression(t.cloneNode(namespace), t.stringLiteral(importName), true);
  172. } else {
  173. NAMESPACE_IMPORT = NAMESPACE_IMPORT = t.memberExpression(t.cloneNode(namespace), t.identifier(importName));
  174. }
  175. const astNodes = {
  176. EXPORTS: meta.exportName,
  177. EXPORT_NAME: exportName,
  178. NAMESPACE_IMPORT
  179. };
  180. if (constantReexports) {
  181. if (stringSpecifiers.has(exportName)) {
  182. return ReexportTemplate.constantComputed(astNodes);
  183. } else {
  184. return ReexportTemplate.constant(astNodes);
  185. }
  186. } else {
  187. return ReexportTemplate.spec(astNodes);
  188. }
  189. });
  190. };
  191. function buildESModuleHeader(metadata, enumerableModuleMeta = false) {
  192. return (enumerableModuleMeta ? _template.default.statement`
  193. EXPORTS.__esModule = true;
  194. ` : _template.default.statement`
  195. Object.defineProperty(EXPORTS, "__esModule", {
  196. value: true,
  197. });
  198. `)({
  199. EXPORTS: metadata.exportName
  200. });
  201. }
  202. function buildNamespaceReexport(metadata, namespace, constantReexports) {
  203. return (constantReexports ? _template.default.statement`
  204. Object.keys(NAMESPACE).forEach(function(key) {
  205. if (key === "default" || key === "__esModule") return;
  206. VERIFY_NAME_LIST;
  207. if (key in EXPORTS && EXPORTS[key] === NAMESPACE[key]) return;
  208. EXPORTS[key] = NAMESPACE[key];
  209. });
  210. ` : _template.default.statement`
  211. Object.keys(NAMESPACE).forEach(function(key) {
  212. if (key === "default" || key === "__esModule") return;
  213. VERIFY_NAME_LIST;
  214. if (key in EXPORTS && EXPORTS[key] === NAMESPACE[key]) return;
  215. Object.defineProperty(EXPORTS, key, {
  216. enumerable: true,
  217. get: function() {
  218. return NAMESPACE[key];
  219. },
  220. });
  221. });
  222. `)({
  223. NAMESPACE: namespace,
  224. EXPORTS: metadata.exportName,
  225. VERIFY_NAME_LIST: metadata.exportNameListName ? (0, _template.default)`
  226. if (Object.prototype.hasOwnProperty.call(EXPORTS_LIST, key)) return;
  227. `({
  228. EXPORTS_LIST: metadata.exportNameListName
  229. }) : null
  230. });
  231. }
  232. function buildExportNameListDeclaration(programPath, metadata) {
  233. const exportedVars = Object.create(null);
  234. for (const data of metadata.local.values()) {
  235. for (const name of data.names) {
  236. exportedVars[name] = true;
  237. }
  238. }
  239. let hasReexport = false;
  240. for (const data of metadata.source.values()) {
  241. for (const exportName of data.reexports.keys()) {
  242. exportedVars[exportName] = true;
  243. }
  244. for (const exportName of data.reexportNamespace) {
  245. exportedVars[exportName] = true;
  246. }
  247. hasReexport = hasReexport || !!data.reexportAll;
  248. }
  249. if (!hasReexport || Object.keys(exportedVars).length === 0) return null;
  250. const name = programPath.scope.generateUidIdentifier("exportNames");
  251. delete exportedVars.default;
  252. return {
  253. name: name.name,
  254. statement: t.variableDeclaration("var", [t.variableDeclarator(name, t.valueToNode(exportedVars))])
  255. };
  256. }
  257. function buildExportInitializationStatements(programPath, metadata, constantReexports = false) {
  258. const initStatements = [];
  259. const exportNames = [];
  260. for (const [localName, data] of metadata.local) {
  261. if (data.kind === "import") {} else if (data.kind === "hoisted") {
  262. initStatements.push(buildInitStatement(metadata, data.names, t.identifier(localName)));
  263. } else {
  264. exportNames.push(...data.names);
  265. }
  266. }
  267. for (const data of metadata.source.values()) {
  268. if (!constantReexports) {
  269. initStatements.push(...buildReexportsFromMeta(metadata, data, false));
  270. }
  271. for (const exportName of data.reexportNamespace) {
  272. exportNames.push(exportName);
  273. }
  274. }
  275. initStatements.push(...chunk(exportNames, 100).map(members => {
  276. return buildInitStatement(metadata, members, programPath.scope.buildUndefinedNode());
  277. }));
  278. return initStatements;
  279. }
  280. const InitTemplate = {
  281. computed: _template.default.expression`EXPORTS["NAME"] = VALUE`,
  282. default: _template.default.expression`EXPORTS.NAME = VALUE`
  283. };
  284. function buildInitStatement(metadata, exportNames, initExpr) {
  285. const {
  286. stringSpecifiers,
  287. exportName: EXPORTS
  288. } = metadata;
  289. return t.expressionStatement(exportNames.reduce((acc, exportName) => {
  290. const params = {
  291. EXPORTS,
  292. NAME: exportName,
  293. VALUE: acc
  294. };
  295. if (stringSpecifiers.has(exportName)) {
  296. return InitTemplate.computed(params);
  297. } else {
  298. return InitTemplate.default(params);
  299. }
  300. }, initExpr));
  301. }
  302. function chunk(array, size) {
  303. const chunks = [];
  304. for (let i = 0; i < array.length; i += size) {
  305. chunks.push(array.slice(i, i + size));
  306. }
  307. return chunks;
  308. }