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.

550 lines
17 KiB

  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, options) => {
  9. var _api$assumption, _options$allowArrayLi, _api$assumption2;
  10. api.assertVersion(7);
  11. const {
  12. useBuiltIns = false
  13. } = options;
  14. const iterableIsArray = (_api$assumption = api.assumption("iterableIsArray")) != null ? _api$assumption : options.loose;
  15. const arrayLikeIsIterable = (_options$allowArrayLi = options.allowArrayLike) != null ? _options$allowArrayLi : api.assumption("arrayLikeIsIterable");
  16. const objectRestNoSymbols = (_api$assumption2 = api.assumption("objectRestNoSymbols")) != null ? _api$assumption2 : options.loose;
  17. function getExtendsHelper(file) {
  18. return useBuiltIns ? _core.types.memberExpression(_core.types.identifier("Object"), _core.types.identifier("assign")) : file.addHelper("extends");
  19. }
  20. function variableDeclarationHasPattern(node) {
  21. for (const declar of node.declarations) {
  22. if (_core.types.isPattern(declar.id)) {
  23. return true;
  24. }
  25. }
  26. return false;
  27. }
  28. function hasRest(pattern) {
  29. for (const elem of pattern.elements) {
  30. if (_core.types.isRestElement(elem)) {
  31. return true;
  32. }
  33. }
  34. return false;
  35. }
  36. function hasObjectRest(pattern) {
  37. for (const elem of pattern.properties) {
  38. if (_core.types.isRestElement(elem)) {
  39. return true;
  40. }
  41. }
  42. return false;
  43. }
  44. const STOP_TRAVERSAL = {};
  45. const arrayUnpackVisitor = (node, ancestors, state) => {
  46. if (!ancestors.length) {
  47. return;
  48. }
  49. if (_core.types.isIdentifier(node) && _core.types.isReferenced(node, ancestors[ancestors.length - 1]) && state.bindings[node.name]) {
  50. state.deopt = true;
  51. throw STOP_TRAVERSAL;
  52. }
  53. };
  54. class DestructuringTransformer {
  55. constructor(opts) {
  56. this.blockHoist = opts.blockHoist;
  57. this.operator = opts.operator;
  58. this.arrays = {};
  59. this.nodes = opts.nodes || [];
  60. this.scope = opts.scope;
  61. this.kind = opts.kind;
  62. this.iterableIsArray = opts.iterableIsArray;
  63. this.arrayLikeIsIterable = opts.arrayLikeIsIterable;
  64. this.addHelper = opts.addHelper;
  65. }
  66. buildVariableAssignment(id, init) {
  67. let op = this.operator;
  68. if (_core.types.isMemberExpression(id)) op = "=";
  69. let node;
  70. if (op) {
  71. node = _core.types.expressionStatement(_core.types.assignmentExpression(op, id, _core.types.cloneNode(init) || this.scope.buildUndefinedNode()));
  72. } else {
  73. node = _core.types.variableDeclaration(this.kind, [_core.types.variableDeclarator(id, _core.types.cloneNode(init))]);
  74. }
  75. node._blockHoist = this.blockHoist;
  76. return node;
  77. }
  78. buildVariableDeclaration(id, init) {
  79. const declar = _core.types.variableDeclaration("var", [_core.types.variableDeclarator(_core.types.cloneNode(id), _core.types.cloneNode(init))]);
  80. declar._blockHoist = this.blockHoist;
  81. return declar;
  82. }
  83. push(id, _init) {
  84. const init = _core.types.cloneNode(_init);
  85. if (_core.types.isObjectPattern(id)) {
  86. this.pushObjectPattern(id, init);
  87. } else if (_core.types.isArrayPattern(id)) {
  88. this.pushArrayPattern(id, init);
  89. } else if (_core.types.isAssignmentPattern(id)) {
  90. this.pushAssignmentPattern(id, init);
  91. } else {
  92. this.nodes.push(this.buildVariableAssignment(id, init));
  93. }
  94. }
  95. toArray(node, count) {
  96. if (this.iterableIsArray || _core.types.isIdentifier(node) && this.arrays[node.name]) {
  97. return node;
  98. } else {
  99. return this.scope.toArray(node, count, this.arrayLikeIsIterable);
  100. }
  101. }
  102. pushAssignmentPattern({
  103. left,
  104. right
  105. }, valueRef) {
  106. const tempId = this.scope.generateUidIdentifierBasedOnNode(valueRef);
  107. this.nodes.push(this.buildVariableDeclaration(tempId, valueRef));
  108. const tempConditional = _core.types.conditionalExpression(_core.types.binaryExpression("===", _core.types.cloneNode(tempId), this.scope.buildUndefinedNode()), right, _core.types.cloneNode(tempId));
  109. if (_core.types.isPattern(left)) {
  110. let patternId;
  111. let node;
  112. if (this.kind === "const" || this.kind === "let") {
  113. patternId = this.scope.generateUidIdentifier(tempId.name);
  114. node = this.buildVariableDeclaration(patternId, tempConditional);
  115. } else {
  116. patternId = tempId;
  117. node = _core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.cloneNode(tempId), tempConditional));
  118. }
  119. this.nodes.push(node);
  120. this.push(left, patternId);
  121. } else {
  122. this.nodes.push(this.buildVariableAssignment(left, tempConditional));
  123. }
  124. }
  125. pushObjectRest(pattern, objRef, spreadProp, spreadPropIndex) {
  126. const keys = [];
  127. let allLiteral = true;
  128. for (let i = 0; i < pattern.properties.length; i++) {
  129. const prop = pattern.properties[i];
  130. if (i >= spreadPropIndex) break;
  131. if (_core.types.isRestElement(prop)) continue;
  132. const key = prop.key;
  133. if (_core.types.isIdentifier(key) && !prop.computed) {
  134. keys.push(_core.types.stringLiteral(key.name));
  135. } else if (_core.types.isTemplateLiteral(prop.key)) {
  136. keys.push(_core.types.cloneNode(prop.key));
  137. } else if (_core.types.isLiteral(key)) {
  138. keys.push(_core.types.stringLiteral(String(key.value)));
  139. } else {
  140. keys.push(_core.types.cloneNode(key));
  141. allLiteral = false;
  142. }
  143. }
  144. let value;
  145. if (keys.length === 0) {
  146. value = _core.types.callExpression(getExtendsHelper(this), [_core.types.objectExpression([]), _core.types.cloneNode(objRef)]);
  147. } else {
  148. let keyExpression = _core.types.arrayExpression(keys);
  149. if (!allLiteral) {
  150. keyExpression = _core.types.callExpression(_core.types.memberExpression(keyExpression, _core.types.identifier("map")), [this.addHelper("toPropertyKey")]);
  151. }
  152. value = _core.types.callExpression(this.addHelper(`objectWithoutProperties${objectRestNoSymbols ? "Loose" : ""}`), [_core.types.cloneNode(objRef), keyExpression]);
  153. }
  154. this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
  155. }
  156. pushObjectProperty(prop, propRef) {
  157. if (_core.types.isLiteral(prop.key)) prop.computed = true;
  158. const pattern = prop.value;
  159. const objRef = _core.types.memberExpression(_core.types.cloneNode(propRef), prop.key, prop.computed);
  160. if (_core.types.isPattern(pattern)) {
  161. this.push(pattern, objRef);
  162. } else {
  163. this.nodes.push(this.buildVariableAssignment(pattern, objRef));
  164. }
  165. }
  166. pushObjectPattern(pattern, objRef) {
  167. if (!pattern.properties.length) {
  168. this.nodes.push(_core.types.expressionStatement(_core.types.callExpression(this.addHelper("objectDestructuringEmpty"), [objRef])));
  169. }
  170. if (pattern.properties.length > 1 && !this.scope.isStatic(objRef)) {
  171. const temp = this.scope.generateUidIdentifierBasedOnNode(objRef);
  172. this.nodes.push(this.buildVariableDeclaration(temp, objRef));
  173. objRef = temp;
  174. }
  175. if (hasObjectRest(pattern)) {
  176. let copiedPattern;
  177. for (let i = 0; i < pattern.properties.length; i++) {
  178. const prop = pattern.properties[i];
  179. if (_core.types.isRestElement(prop)) {
  180. break;
  181. }
  182. const key = prop.key;
  183. if (prop.computed && !this.scope.isPure(key)) {
  184. const name = this.scope.generateUidIdentifierBasedOnNode(key);
  185. this.nodes.push(this.buildVariableDeclaration(name, key));
  186. if (!copiedPattern) {
  187. copiedPattern = pattern = Object.assign({}, pattern, {
  188. properties: pattern.properties.slice()
  189. });
  190. }
  191. copiedPattern.properties[i] = Object.assign({}, copiedPattern.properties[i], {
  192. key: name
  193. });
  194. }
  195. }
  196. }
  197. for (let i = 0; i < pattern.properties.length; i++) {
  198. const prop = pattern.properties[i];
  199. if (_core.types.isRestElement(prop)) {
  200. this.pushObjectRest(pattern, objRef, prop, i);
  201. } else {
  202. this.pushObjectProperty(prop, objRef);
  203. }
  204. }
  205. }
  206. canUnpackArrayPattern(pattern, arr) {
  207. if (!_core.types.isArrayExpression(arr)) return false;
  208. if (pattern.elements.length > arr.elements.length) return;
  209. if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) {
  210. return false;
  211. }
  212. for (const elem of pattern.elements) {
  213. if (!elem) return false;
  214. if (_core.types.isMemberExpression(elem)) return false;
  215. }
  216. for (const elem of arr.elements) {
  217. if (_core.types.isSpreadElement(elem)) return false;
  218. if (_core.types.isCallExpression(elem)) return false;
  219. if (_core.types.isMemberExpression(elem)) return false;
  220. }
  221. const bindings = _core.types.getBindingIdentifiers(pattern);
  222. const state = {
  223. deopt: false,
  224. bindings
  225. };
  226. try {
  227. _core.types.traverse(arr, arrayUnpackVisitor, state);
  228. } catch (e) {
  229. if (e !== STOP_TRAVERSAL) throw e;
  230. }
  231. return !state.deopt;
  232. }
  233. pushUnpackedArrayPattern(pattern, arr) {
  234. for (let i = 0; i < pattern.elements.length; i++) {
  235. const elem = pattern.elements[i];
  236. if (_core.types.isRestElement(elem)) {
  237. this.push(elem.argument, _core.types.arrayExpression(arr.elements.slice(i)));
  238. } else {
  239. this.push(elem, arr.elements[i]);
  240. }
  241. }
  242. }
  243. pushArrayPattern(pattern, arrayRef) {
  244. if (!pattern.elements) return;
  245. if (this.canUnpackArrayPattern(pattern, arrayRef)) {
  246. return this.pushUnpackedArrayPattern(pattern, arrayRef);
  247. }
  248. const count = !hasRest(pattern) && pattern.elements.length;
  249. const toArray = this.toArray(arrayRef, count);
  250. if (_core.types.isIdentifier(toArray)) {
  251. arrayRef = toArray;
  252. } else {
  253. arrayRef = this.scope.generateUidIdentifierBasedOnNode(arrayRef);
  254. this.arrays[arrayRef.name] = true;
  255. this.nodes.push(this.buildVariableDeclaration(arrayRef, toArray));
  256. }
  257. for (let i = 0; i < pattern.elements.length; i++) {
  258. let elem = pattern.elements[i];
  259. if (!elem) continue;
  260. let elemRef;
  261. if (_core.types.isRestElement(elem)) {
  262. elemRef = this.toArray(arrayRef);
  263. elemRef = _core.types.callExpression(_core.types.memberExpression(elemRef, _core.types.identifier("slice")), [_core.types.numericLiteral(i)]);
  264. elem = elem.argument;
  265. } else {
  266. elemRef = _core.types.memberExpression(arrayRef, _core.types.numericLiteral(i), true);
  267. }
  268. this.push(elem, elemRef);
  269. }
  270. }
  271. init(pattern, ref) {
  272. if (!_core.types.isArrayExpression(ref) && !_core.types.isMemberExpression(ref)) {
  273. const memo = this.scope.maybeGenerateMemoised(ref, true);
  274. if (memo) {
  275. this.nodes.push(this.buildVariableDeclaration(memo, _core.types.cloneNode(ref)));
  276. ref = memo;
  277. }
  278. }
  279. this.push(pattern, ref);
  280. return this.nodes;
  281. }
  282. }
  283. return {
  284. name: "transform-destructuring",
  285. visitor: {
  286. ExportNamedDeclaration(path) {
  287. const declaration = path.get("declaration");
  288. if (!declaration.isVariableDeclaration()) return;
  289. if (!variableDeclarationHasPattern(declaration.node)) return;
  290. const specifiers = [];
  291. for (const name of Object.keys(path.getOuterBindingIdentifiers(path))) {
  292. specifiers.push(_core.types.exportSpecifier(_core.types.identifier(name), _core.types.identifier(name)));
  293. }
  294. path.replaceWith(declaration.node);
  295. path.insertAfter(_core.types.exportNamedDeclaration(null, specifiers));
  296. },
  297. ForXStatement(path) {
  298. const {
  299. node,
  300. scope
  301. } = path;
  302. const left = node.left;
  303. if (_core.types.isPattern(left)) {
  304. const temp = scope.generateUidIdentifier("ref");
  305. node.left = _core.types.variableDeclaration("var", [_core.types.variableDeclarator(temp)]);
  306. path.ensureBlock();
  307. if (node.body.body.length === 0 && path.isCompletionRecord()) {
  308. node.body.body.unshift(_core.types.expressionStatement(scope.buildUndefinedNode()));
  309. }
  310. node.body.body.unshift(_core.types.expressionStatement(_core.types.assignmentExpression("=", left, temp)));
  311. return;
  312. }
  313. if (!_core.types.isVariableDeclaration(left)) return;
  314. const pattern = left.declarations[0].id;
  315. if (!_core.types.isPattern(pattern)) return;
  316. const key = scope.generateUidIdentifier("ref");
  317. node.left = _core.types.variableDeclaration(left.kind, [_core.types.variableDeclarator(key, null)]);
  318. const nodes = [];
  319. const destructuring = new DestructuringTransformer({
  320. kind: left.kind,
  321. scope: scope,
  322. nodes: nodes,
  323. iterableIsArray,
  324. arrayLikeIsIterable,
  325. addHelper: name => this.addHelper(name)
  326. });
  327. destructuring.init(pattern, key);
  328. path.ensureBlock();
  329. const block = node.body;
  330. block.body = nodes.concat(block.body);
  331. },
  332. CatchClause({
  333. node,
  334. scope
  335. }) {
  336. const pattern = node.param;
  337. if (!_core.types.isPattern(pattern)) return;
  338. const ref = scope.generateUidIdentifier("ref");
  339. node.param = ref;
  340. const nodes = [];
  341. const destructuring = new DestructuringTransformer({
  342. kind: "let",
  343. scope: scope,
  344. nodes: nodes,
  345. iterableIsArray,
  346. arrayLikeIsIterable,
  347. addHelper: name => this.addHelper(name)
  348. });
  349. destructuring.init(pattern, ref);
  350. node.body.body = nodes.concat(node.body.body);
  351. },
  352. AssignmentExpression(path) {
  353. const {
  354. node,
  355. scope
  356. } = path;
  357. if (!_core.types.isPattern(node.left)) return;
  358. const nodes = [];
  359. const destructuring = new DestructuringTransformer({
  360. operator: node.operator,
  361. scope: scope,
  362. nodes: nodes,
  363. iterableIsArray,
  364. arrayLikeIsIterable,
  365. addHelper: name => this.addHelper(name)
  366. });
  367. let ref;
  368. if (path.isCompletionRecord() || !path.parentPath.isExpressionStatement()) {
  369. ref = scope.generateUidIdentifierBasedOnNode(node.right, "ref");
  370. nodes.push(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(ref, node.right)]));
  371. if (_core.types.isArrayExpression(node.right)) {
  372. destructuring.arrays[ref.name] = true;
  373. }
  374. }
  375. destructuring.init(node.left, ref || node.right);
  376. if (ref) {
  377. if (path.parentPath.isArrowFunctionExpression()) {
  378. path.replaceWith(_core.types.blockStatement([]));
  379. nodes.push(_core.types.returnStatement(_core.types.cloneNode(ref)));
  380. } else {
  381. nodes.push(_core.types.expressionStatement(_core.types.cloneNode(ref)));
  382. }
  383. }
  384. path.replaceWithMultiple(nodes);
  385. path.scope.crawl();
  386. },
  387. VariableDeclaration(path) {
  388. const {
  389. node,
  390. scope,
  391. parent
  392. } = path;
  393. if (_core.types.isForXStatement(parent)) return;
  394. if (!parent || !path.container) return;
  395. if (!variableDeclarationHasPattern(node)) return;
  396. const nodeKind = node.kind;
  397. const nodes = [];
  398. let declar;
  399. for (let i = 0; i < node.declarations.length; i++) {
  400. declar = node.declarations[i];
  401. const patternId = declar.init;
  402. const pattern = declar.id;
  403. const destructuring = new DestructuringTransformer({
  404. blockHoist: node._blockHoist,
  405. nodes: nodes,
  406. scope: scope,
  407. kind: node.kind,
  408. iterableIsArray,
  409. arrayLikeIsIterable,
  410. addHelper: name => this.addHelper(name)
  411. });
  412. if (_core.types.isPattern(pattern)) {
  413. destructuring.init(pattern, patternId);
  414. if (+i !== node.declarations.length - 1) {
  415. _core.types.inherits(nodes[nodes.length - 1], declar);
  416. }
  417. } else {
  418. nodes.push(_core.types.inherits(destructuring.buildVariableAssignment(declar.id, _core.types.cloneNode(declar.init)), declar));
  419. }
  420. }
  421. let tail = null;
  422. const nodesOut = [];
  423. for (const node of nodes) {
  424. if (tail !== null && _core.types.isVariableDeclaration(node)) {
  425. tail.declarations.push(...node.declarations);
  426. } else {
  427. node.kind = nodeKind;
  428. nodesOut.push(node);
  429. tail = _core.types.isVariableDeclaration(node) ? node : null;
  430. }
  431. }
  432. for (const nodeOut of nodesOut) {
  433. if (!nodeOut.declarations) continue;
  434. for (const declaration of nodeOut.declarations) {
  435. const {
  436. name
  437. } = declaration.id;
  438. if (scope.bindings[name]) {
  439. scope.bindings[name].kind = nodeOut.kind;
  440. }
  441. }
  442. }
  443. if (nodesOut.length === 1) {
  444. path.replaceWith(nodesOut[0]);
  445. } else {
  446. path.replaceWithMultiple(nodesOut);
  447. }
  448. }
  449. }
  450. };
  451. });
  452. exports.default = _default;